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