headers display conf and custom header ui - cache version
[claws.git] / src / prefs_headers.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2001 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 <gtk/gtk.h>
28 #include <gdk/gdkkeysyms.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <errno.h>
33
34 #include "intl.h"
35 #include "main.h"
36 #include "prefs.h"
37 #include "prefs_headers.h"
38 #include "prefs_common.h"
39 #include "prefs_account.h"
40 #include "mainwindow.h"
41 #include "foldersel.h"
42 #include "manage_window.h"
43 #include "customheader.h"
44 #include "utils.h"
45 #include "gtkutils.h"
46 #include "alertpanel.h"
47 #include "folder.h"
48
49 static struct Headers {
50         GtkWidget *window;
51
52         /*
53         GtkWidget *close_btn;
54         */
55         GtkWidget *ok_btn;
56         GtkWidget *cancel_btn;
57
58         GtkWidget *hdr_combo;
59         GtkWidget *hdr_entry;
60         GtkWidget *key_entry;
61         GtkWidget *headers_clist;
62 } headers;
63
64 /*
65    parameter name, default value, pointer to the prefs variable, data type,
66    pointer to the widget pointer,
67    pointer to the function for data setting,
68    pointer to the function for widget setting
69  */
70
71 #define VSPACING                12
72 #define VSPACING_NARROW         4
73 #define DEFAULT_ENTRY_WIDTH     80
74 #define PREFSBUFSIZE            1024
75
76 /* widget creating functions */
77 static void prefs_headers_create                (void);
78
79 static void prefs_headers_set_dialog    (PrefsAccount * ac);
80 static void prefs_headers_set_list      (PrefsAccount * ac);
81 static gint prefs_headers_clist_set_row (PrefsAccount * ac,
82                                          gint    row);
83
84 /* callback functions */
85 static void prefs_headers_select_dest_cb        (void);
86 static void prefs_headers_register_cb   (void);
87 static void prefs_headers_substitute_cb (void);
88 static void prefs_headers_delete_cb     (void);
89 static void prefs_headers_up            (void);
90 static void prefs_headers_down          (void);
91 static void prefs_headers_select                (GtkCList       *clist,
92                                          gint            row,
93                                          gint            column,
94                                          GdkEvent       *event);
95
96 static void prefs_headers_key_pressed   (GtkWidget      *widget,
97                                          GdkEventKey    *event,
98                                          gpointer        data);
99 /*
100 static void prefs_headers_close         (GtkButton      *button);
101 */
102 static void prefs_headers_ok            (GtkButton      *button);
103 static void prefs_headers_cancel        (GtkButton      *button);
104
105 static PrefsAccount * cur_ac = NULL;
106
107 void prefs_headers_open(PrefsAccount * ac)
108 {
109         if (!headers.window) {
110                 prefs_headers_create();
111         }
112
113         manage_window_set_transient(GTK_WINDOW(headers.window));
114         /*
115         gtk_widget_grab_focus(headers.close_btn);
116         */
117         gtk_widget_grab_focus(headers.ok_btn);
118
119         prefs_headers_set_dialog(ac);
120
121         cur_ac = ac;
122
123         gtk_widget_show(headers.window);
124 }
125
126 static void prefs_headers_create(void)
127 {
128         GtkWidget *window;
129         GtkWidget *vbox;
130
131         /*      GtkWidget *close_btn; */
132         GtkWidget *ok_btn;
133         GtkWidget *cancel_btn;
134
135         GtkWidget *confirm_area;
136
137         GtkWidget *vbox1;
138
139         GtkWidget *table1;
140         GtkWidget *hdr_label;
141         GtkWidget *hdr_combo;
142         GtkWidget *key_label;
143         GtkWidget *key_entry;
144
145         GtkWidget *reg_hbox;
146         GtkWidget *btn_hbox;
147         GtkWidget *arrow;
148         GtkWidget *reg_btn;
149         GtkWidget *subst_btn;
150         GtkWidget *del_btn;
151
152         GtkWidget *ch_hbox;
153         GtkWidget *ch_scrolledwin;
154         GtkWidget *headers_clist;
155
156         GtkWidget *btn_vbox;
157         GtkWidget *up_btn;
158         GtkWidget *down_btn;
159
160         gchar *title[] = {_("Custom headers")};
161
162         debug_print(_("Creating headers setting window...\n"));
163
164         window = gtk_window_new (GTK_WINDOW_DIALOG);
165         gtk_container_set_border_width (GTK_CONTAINER (window), 8);
166         gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
167         gtk_window_set_modal (GTK_WINDOW (window), TRUE);
168         gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
169
170         vbox = gtk_vbox_new (FALSE, 6);
171         gtk_widget_show (vbox);
172         gtk_container_add (GTK_CONTAINER (window), vbox);
173
174         gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
175                                 &cancel_btn, _("Cancel"), NULL, NULL);
176         /*
177         gtkut_button_set_create (&confirm_area, &close_btn, _("Close"),
178                                  NULL, NULL, NULL, NULL);
179         */
180         gtk_widget_show (confirm_area);
181         gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
182         /*
183         gtk_widget_grab_default (close_btn);
184         */
185         gtk_widget_grab_default (ok_btn);
186
187         gtk_window_set_title (GTK_WINDOW(window),
188                               _("Headers setting"));
189         gtk_signal_connect (GTK_OBJECT(window), "delete_event",
190                             GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete), NULL);
191         gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
192                             GTK_SIGNAL_FUNC(prefs_headers_key_pressed), NULL);
193         gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
194                             GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
195         gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
196                             GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
197         gtk_signal_connect (GTK_OBJECT(ok_btn), "clicked",
198                             GTK_SIGNAL_FUNC(prefs_headers_ok), NULL);
199         gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
200                             GTK_SIGNAL_FUNC(prefs_headers_cancel), NULL);
201
202         vbox1 = gtk_vbox_new (FALSE, VSPACING);
203         gtk_widget_show (vbox1);
204         gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
205         gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
206
207         table1 = gtk_table_new (2, 2, FALSE);
208         gtk_widget_show (table1);
209         gtk_box_pack_start (GTK_BOX (vbox1), table1,
210                             FALSE, FALSE, 0);
211         gtk_table_set_row_spacings (GTK_TABLE (table1), 8);
212         gtk_table_set_col_spacings (GTK_TABLE (table1), 8);
213
214         hdr_label = gtk_label_new (_("Header"));
215         gtk_widget_show (hdr_label);
216         gtk_table_attach (GTK_TABLE (table1), hdr_label, 0, 1, 0, 1,
217                           GTK_EXPAND | GTK_SHRINK | GTK_FILL,
218                           0, 0, 0);
219         gtk_misc_set_alignment (GTK_MISC (hdr_label), 0, 0.5);
220         
221         hdr_combo = gtk_combo_new ();
222         gtk_widget_show (hdr_combo);
223         gtk_table_attach (GTK_TABLE (table1), hdr_combo, 0, 1, 1, 2,
224                           GTK_EXPAND | GTK_SHRINK | GTK_FILL,
225                           0, 0, 0);
226         gtk_widget_set_usize (hdr_combo, 150 /* 96 */, -1);
227         gtkut_combo_set_items (GTK_COMBO (hdr_combo),
228                                "User-Agent", "X-Operating-System", NULL);
229
230         key_label = gtk_label_new (_("Value"));
231         gtk_widget_show (key_label);
232         gtk_table_attach (GTK_TABLE (table1), key_label, 1, 2, 0, 1,
233                           GTK_EXPAND | GTK_SHRINK | GTK_FILL,
234                           0, 0, 0);
235         gtk_misc_set_alignment (GTK_MISC (key_label), 0, 0.5);
236         
237         key_entry = gtk_entry_new ();
238         gtk_widget_show (key_entry);
239         gtk_table_attach (GTK_TABLE (table1), key_entry, 1, 2, 1, 2,
240                           GTK_EXPAND | GTK_SHRINK | GTK_FILL,
241                           0, 0, 0);
242
243         /* register / substitute / delete */
244
245         reg_hbox = gtk_hbox_new (FALSE, 4);
246         gtk_widget_show (reg_hbox);
247         gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox,
248                             FALSE, FALSE, 0);
249
250         arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
251         gtk_widget_show (arrow);
252         gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0);
253         gtk_widget_set_usize (arrow, -1, 16);
254
255         btn_hbox = gtk_hbox_new (TRUE, 4);
256         gtk_widget_show (btn_hbox);
257         gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0);
258
259         reg_btn = gtk_button_new_with_label (_("Add"));
260         gtk_widget_show (reg_btn);
261         gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0);
262         gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
263                             GTK_SIGNAL_FUNC (prefs_headers_register_cb), NULL);
264
265         subst_btn = gtk_button_new_with_label (_(" Substitute "));
266         gtk_widget_show (subst_btn);
267         gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0);
268         gtk_signal_connect (GTK_OBJECT (subst_btn), "clicked",
269                             GTK_SIGNAL_FUNC (prefs_headers_substitute_cb),
270                             NULL);
271
272         del_btn = gtk_button_new_with_label (_("Delete"));
273         gtk_widget_show (del_btn);
274         gtk_box_pack_start (GTK_BOX (btn_hbox), del_btn, FALSE, TRUE, 0);
275         gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
276                             GTK_SIGNAL_FUNC (prefs_headers_delete_cb), NULL);
277
278
279         ch_hbox = gtk_hbox_new (FALSE, 8);
280         gtk_widget_show (ch_hbox);
281         gtk_box_pack_start (GTK_BOX (vbox1), ch_hbox,
282                             TRUE, TRUE, 0);
283
284         ch_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
285         gtk_widget_set_usize (ch_scrolledwin, -1, 100);
286         gtk_widget_show (ch_scrolledwin);
287         gtk_box_pack_start (GTK_BOX (ch_hbox), ch_scrolledwin,
288                             TRUE, TRUE, 0);
289         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (ch_scrolledwin),
290                                         GTK_POLICY_AUTOMATIC,
291                                         GTK_POLICY_AUTOMATIC);
292
293         headers_clist = gtk_clist_new_with_titles(1, title);
294         gtk_widget_show (headers_clist);
295         gtk_container_add (GTK_CONTAINER (ch_scrolledwin), headers_clist);
296         gtk_clist_set_column_width (GTK_CLIST (headers_clist), 0, 80);
297         gtk_clist_set_selection_mode (GTK_CLIST (headers_clist),
298                                       GTK_SELECTION_BROWSE);
299         GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (headers_clist)->column[0].button,
300                                 GTK_CAN_FOCUS);
301         gtk_signal_connect (GTK_OBJECT (headers_clist), "select_row",
302                             GTK_SIGNAL_FUNC (prefs_headers_select),
303                             NULL);
304
305
306         btn_vbox = gtk_vbox_new (FALSE, 8);
307         gtk_widget_show (btn_vbox);
308         gtk_box_pack_start (GTK_BOX (ch_hbox), btn_vbox, FALSE, FALSE, 0);
309
310         up_btn = gtk_button_new_with_label (_("Up"));
311         gtk_widget_show (up_btn);
312         gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
313         gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
314                             GTK_SIGNAL_FUNC (prefs_headers_up), NULL);
315
316         down_btn = gtk_button_new_with_label (_("Down"));
317         gtk_widget_show (down_btn);
318         gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
319         gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
320                             GTK_SIGNAL_FUNC (prefs_headers_down), NULL);
321
322
323         gtk_widget_show_all(window);
324
325         headers.window    = window;
326         /*      headers.close_btn = close_btn; */
327         headers.ok_btn = ok_btn;
328         headers.cancel_btn = cancel_btn;
329
330         headers.hdr_combo  = hdr_combo;
331         headers.hdr_entry  = GTK_COMBO (hdr_combo)->entry;
332         headers.key_entry  = key_entry;
333         headers.headers_clist   = headers_clist;
334 }
335
336 void prefs_headers_read_config(PrefsAccount * ac)
337 {
338         gchar *rcpath;
339         FILE *fp;
340         gchar buf[PREFSBUFSIZE];
341         CustomHeader *ch;
342
343         debug_print(_("Reading headers configuration...\n"));
344
345         rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, HEADERS_RC, NULL);
346         if ((fp = fopen(rcpath, "r")) == NULL) {
347                 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
348                 g_free(rcpath);
349                 ac->customhdr_list = NULL;
350                 return;
351         }
352         g_free(rcpath);
353
354         /* remove all previous headers list */
355         while (ac->customhdr_list != NULL) {
356                 ch = (CustomHeader *)ac->customhdr_list->data;
357                 custom_header_free(ch);
358                 ac->customhdr_list = g_slist_remove(ac->customhdr_list, ch);
359         }
360  
361         while (fgets(buf, sizeof(buf), fp) != NULL) {
362                 g_strchomp(buf);
363                 ch = custom_header_read_str(buf);
364                 if (ch) {
365                         if (ch->account_id == ac->account_id)
366                                 ac->customhdr_list =
367                                         g_slist_append(ac->customhdr_list, ch);
368                         else
369                                 custom_header_free(ch);
370                 }
371         }
372  
373         fclose(fp);
374 }
375
376 void prefs_headers_write_config(PrefsAccount * ac)
377 {
378         gchar *rcpath;
379         PrefFile *pfile;
380         GSList *cur;
381         gchar buf[PREFSBUFSIZE];
382         FILE * fp;
383         CustomHeader *ch;
384
385         GSList *all_hdrs = NULL;
386
387         debug_print(_("Writing headers configuration...\n"));
388
389         rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, HEADERS_RC, NULL);
390
391         if ((fp = fopen(rcpath, "r")) == NULL) {
392                 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
393         }
394         else {
395                 all_hdrs = NULL;
396
397                 while (fgets(buf, sizeof(buf), fp) != NULL) {
398                         g_strchomp(buf);
399                         ch = custom_header_read_str(buf);
400                         if (ch) {
401                                 if (ch->account_id != ac->account_id)
402                                         all_hdrs =
403                                                 g_slist_append(all_hdrs, ch);
404                                 else
405                                         custom_header_free(ch);
406                         }
407                 }
408
409                 fclose(fp);
410         }
411
412         if ((pfile = prefs_write_open(rcpath)) == NULL) {
413                 g_warning(_("failed to write configuration to file\n"));
414                 g_free(rcpath);
415                 return;
416         }
417
418         for (cur = all_hdrs; cur != NULL; cur = cur->next) {
419                 CustomHeader *hdr = (CustomHeader *)cur->data;
420                 gchar *chstr;
421
422                 chstr = custom_header_get_str(hdr);
423                 if (fputs(chstr, pfile->fp) == EOF ||
424                     fputc('\n', pfile->fp) == EOF) {
425                         FILE_OP_ERROR(rcpath, "fputs || fputc");
426                         prefs_write_close_revert(pfile);
427                         g_free(rcpath);
428                         g_free(chstr);
429                         return;
430                 }
431                 g_free(chstr);
432         }
433
434         for (cur = ac->customhdr_list; cur != NULL; cur = cur->next) {
435                 CustomHeader *hdr = (CustomHeader *)cur->data;
436                 gchar *chstr;
437
438                 chstr = custom_header_get_str(hdr);
439                 if (fputs(chstr, pfile->fp) == EOF ||
440                     fputc('\n', pfile->fp) == EOF) {
441                         FILE_OP_ERROR(rcpath, "fputs || fputc");
442                         prefs_write_close_revert(pfile);
443                         g_free(rcpath);
444                         g_free(chstr);
445                         return;
446                 }
447                 g_free(chstr);
448         }
449
450         g_free(rcpath);
451
452         while (all_hdrs != NULL) {
453                 ch = (CustomHeader *)all_hdrs->data;
454                 custom_header_free(ch);
455                 all_hdrs = g_slist_remove(all_hdrs, ch);
456         }
457
458         if (prefs_write_close(pfile) < 0) {
459                 g_warning(_("failed to write configuration to file\n"));
460                 return;
461         }
462 }
463
464 static void prefs_headers_set_dialog(PrefsAccount * ac)
465 {
466         GtkCList *clist = GTK_CLIST(headers.headers_clist);
467         GSList *cur;
468         gchar *ch_str[1];
469         gint row;
470
471         gtk_clist_freeze(clist);
472         gtk_clist_clear(clist);
473
474         ch_str[0] = _("(New)");
475         row = gtk_clist_append(clist, ch_str);
476         gtk_clist_set_row_data(clist, row, NULL);
477
478         for (cur = ac->customhdr_list; cur != NULL; cur = cur->next) {
479                 CustomHeader *ch = (CustomHeader *)cur->data;
480
481                 ch_str[0] = g_strdup_printf("%s: %s", ch->name, ch->value);
482                 row = gtk_clist_append(clist, ch_str);
483                 gtk_clist_set_row_data(clist, row, ch);
484
485                 g_free(ch_str[0]);
486         }
487
488         gtk_clist_thaw(clist);
489 }
490
491 static void prefs_headers_set_list(PrefsAccount * ac)
492 {
493         gint row = 1;
494         CustomHeader *ch;
495
496         g_slist_free(ac->customhdr_list);
497         ac->customhdr_list = NULL;
498
499         while ((ch = gtk_clist_get_row_data(GTK_CLIST(headers.headers_clist),
500                 row)) != NULL) {
501                 ac->customhdr_list = g_slist_append(ac->customhdr_list,
502                                                       ch);
503                 row++;
504         }
505 }
506
507 #define GET_ENTRY(entry) \
508         entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
509
510 static gint prefs_headers_clist_set_row(PrefsAccount * ac, gint row)
511 {
512         GtkCList *clist = GTK_CLIST(headers.headers_clist);
513         CustomHeader *ch;
514         gchar *entry_text;
515         gchar *ch_str[1];
516
517         g_return_val_if_fail(row != 0, -1);
518
519         GET_ENTRY(headers.hdr_entry);
520         if (entry_text[0] == '\0') {
521                 alertpanel_error(_("Header name is not set."));
522                 return -1;
523         }
524
525         ch = g_new0(CustomHeader, 1);
526
527         ch->account_id = ac->account_id;
528
529         ch->name = g_strdup(entry_text);
530
531         GET_ENTRY(headers.key_entry);
532         if (entry_text[0] != '\0')
533                 ch->value = g_strdup(entry_text);
534
535         ch_str[0] = g_strdup_printf("%s: %s", ch->name, ch->value);
536
537         if (row < 0)
538                 row = gtk_clist_append(clist, ch_str);
539         else {
540                 CustomHeader *tmpch;
541
542                 gtk_clist_set_text(clist, row, 0, ch_str[0]);
543                 tmpch = gtk_clist_get_row_data(clist, row);
544                 if (tmpch)
545                         custom_header_free(tmpch);
546         }
547
548         gtk_clist_set_row_data(clist, row, ch);
549
550         g_free(ch_str[0]);
551
552         prefs_headers_set_list(cur_ac);
553
554         return row;
555 }
556
557 static void prefs_headers_register_cb(void)
558 {
559         prefs_headers_clist_set_row(cur_ac, -1);
560 }
561
562 static void prefs_headers_substitute_cb(void)
563 {
564         GtkCList *clist = GTK_CLIST(headers.headers_clist);
565         CustomHeader *ch;
566         gint row;
567
568         if (!clist->selection) return;
569
570         row = GPOINTER_TO_INT(clist->selection->data);
571         if (row == 0) return;
572
573         ch = gtk_clist_get_row_data(clist, row);
574         if (!ch) return;
575
576         prefs_headers_clist_set_row(cur_ac, row);
577 }
578
579 static void prefs_headers_delete_cb(void)
580 {
581         GtkCList *clist = GTK_CLIST(headers.headers_clist);
582         CustomHeader *ch;
583         gint row;
584
585         if (!clist->selection) return;
586         row = GPOINTER_TO_INT(clist->selection->data);
587         if (row == 0) return;
588
589         if (alertpanel(_("Delete header"),
590                        _("Do you really want to delete this header?"),
591                        _("Yes"), _("No"), NULL) == G_ALERTALTERNATE)
592                 return;
593
594         ch = gtk_clist_get_row_data(clist, row);
595         custom_header_free(ch);
596         gtk_clist_remove(clist, row);
597         cur_ac->customhdr_list = g_slist_remove(cur_ac->customhdr_list, ch);
598 }
599
600 static void prefs_headers_up(void)
601 {
602         GtkCList *clist = GTK_CLIST(headers.headers_clist);
603         gint row;
604
605         if (!clist->selection) return;
606
607         row = GPOINTER_TO_INT(clist->selection->data);
608         if (row > 1) {
609                 gtk_clist_row_move(clist, row, row - 1);
610                 prefs_headers_set_list(cur_ac);
611         }
612 }
613
614 static void prefs_headers_down(void)
615 {
616         GtkCList *clist = GTK_CLIST(headers.headers_clist);
617         gint row;
618
619         if (!clist->selection) return;
620
621         row = GPOINTER_TO_INT(clist->selection->data);
622         if (row > 0 && row < clist->rows - 1) {
623                 gtk_clist_row_move(clist, row, row + 1);
624                 prefs_headers_set_list(cur_ac);
625         }
626 }
627
628 #define ENTRY_SET_TEXT(entry, str) \
629         gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
630
631 static void prefs_headers_select(GtkCList *clist, gint row, gint column,
632                                 GdkEvent *event)
633 {
634         CustomHeader *ch;
635         CustomHeader default_ch = { 0, "", NULL };
636  
637         ch = gtk_clist_get_row_data(clist, row);
638         if (!ch)
639                 ch = &default_ch;
640  
641         ENTRY_SET_TEXT(headers.hdr_entry, ch->name);
642         ENTRY_SET_TEXT(headers.key_entry, ch->value);
643 }
644
645 static void prefs_headers_key_pressed(GtkWidget *widget, GdkEventKey *event,
646                                      gpointer data)
647 {
648         if (event && event->keyval == GDK_Escape)
649                 gtk_widget_hide(headers.window);
650 }
651
652 static void prefs_headers_ok(GtkButton *button)
653 {
654         prefs_headers_write_config(cur_ac);
655         gtk_widget_hide(headers.window);
656 }
657
658 static void prefs_headers_cancel(GtkButton *button)
659 {
660         /*
661         prefs_headers_write_config(cur_ac); 
662         */
663         prefs_headers_read_config(cur_ac); 
664         gtk_widget_hide(headers.window);
665 }