86883d4c6b021286d2da67d3926de5e45890be2b
[claws.git] / src / prefs_display_header.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 "prefs.h"
36 #include "prefs_display_header.h"
37 #include "prefs_common.h"
38 #include "manage_window.h"
39 #include "alertpanel.h"
40 #include "displayheader.h"
41 #include "utils.h"
42 #include "gtkutils.h"
43
44 static struct DisplayHeader {
45         GtkWidget *window;
46
47         GtkWidget *ok_btn;
48         GtkWidget *cancel_btn;
49
50         GtkWidget *hdr_combo;
51         GtkWidget *hdr_entry;
52         GtkWidget *key_check;
53         GtkWidget *headers_clist;
54         GtkWidget *hidden_headers_clist;
55
56         GtkWidget *other_headers;
57 } dispheader;
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_header_create (void);
73
74 static void prefs_display_header_set_dialog     (void);
75 static void prefs_display_header_set_list       (void);
76 static gint prefs_display_header_clist_set_row  (gboolean hidden);
77
78 /* callback functions */
79 static void prefs_display_header_register_cb    (GtkButton      *btn,
80                                                  gpointer        hidden_data);
81 static void prefs_display_header_delete_cb      (GtkButton      *btn,
82                                                  gpointer        clist_data);
83 static void prefs_display_header_up             (void);
84 static void prefs_display_header_down           (void);
85
86 static void prefs_display_header_row_moved      (GtkCList       *clist,
87                                                  gint            source_row,
88                                                  gint            dest_row,
89                                                  gpointer        data);
90
91 static void prefs_display_header_key_pressed    (GtkWidget      *widget,
92                                                  GdkEventKey    *event,
93                                                  gpointer        data);
94 static void prefs_display_header_ok             (void);
95 static void prefs_display_header_cancel         (void);
96 static gint prefs_display_header_deleted        (GtkWidget      *widget,
97                                                  GdkEventAny    *event,
98                                                  gpointer        data);
99
100 static gchar *defaults[] =
101 {
102         "From",
103         "To",
104         "Cc",
105         "Reply-To",
106         "Newsgroups",
107         "Followup-To",
108         "Subject",
109         "Date",
110         "Sender",
111         "Organization",
112         "X-Mailer",
113         "X-Newsreader",
114         "User-Agent",
115         "-Received",
116         "-Message-Id",
117         "-In-Reply-To",
118         "-References",
119         "-Mime-Version",
120         "-Content-Type",
121         "-Content-Transfer-Encoding",
122         "-X-UIDL",
123         "-Precedence",
124         "-Status",
125         "-Priority",
126         "-X-Face"
127 };
128
129 static void prefs_display_header_set_default(void)
130 {
131         gint i;
132         DisplayHeaderProp *dp;
133
134         for(i = 0; i < sizeof(defaults) / sizeof(defaults[0]); i++) {
135                 dp = display_header_prop_read_str(defaults[i]);
136                 prefs_common.disphdr_list =
137                         g_slist_append(prefs_common.disphdr_list, dp);
138         }
139 }
140
141 void prefs_display_header_open(void)
142 {
143         if (!dispheader.window) {
144                 prefs_display_header_create();
145         }
146
147         manage_window_set_transient(GTK_WINDOW(dispheader.window));
148         gtk_widget_grab_focus(dispheader.ok_btn);
149
150         prefs_display_header_set_dialog();
151
152         gtk_widget_show(dispheader.window);
153 }
154
155 static void prefs_display_header_create(void)
156 {
157         GtkWidget *window;
158         GtkWidget *vbox;
159         GtkWidget *btn_hbox;
160         GtkWidget *ok_btn;
161         GtkWidget *cancel_btn;
162         GtkWidget *confirm_area;
163
164         GtkWidget *vbox1;
165
166         GtkWidget *hbox1;
167         GtkWidget *hdr_label;
168         GtkWidget *hdr_combo;
169
170         GtkWidget *btn_vbox;
171         GtkWidget *reg_btn;
172         GtkWidget *del_btn;
173         GtkWidget *up_btn;
174         GtkWidget *down_btn;
175
176         GtkWidget *clist_hbox;
177         GtkWidget *clist_hbox1;
178         GtkWidget *clist_hbox2;
179         GtkWidget *clist_scrolledwin;
180         GtkWidget *headers_clist;
181         GtkWidget *hidden_headers_clist;
182
183         GtkWidget *checkbtn_other_headers;
184
185         gchar *title[1];
186
187         debug_print(_("Creating display header setting window...\n"));
188
189         window = gtk_window_new (GTK_WINDOW_DIALOG);
190         gtk_container_set_border_width (GTK_CONTAINER (window), 8);
191         gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
192         gtk_window_set_modal (GTK_WINDOW (window), TRUE);
193         gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
194
195         vbox = gtk_vbox_new (FALSE, 6);
196         gtk_widget_show (vbox);
197         gtk_container_add (GTK_CONTAINER (window), vbox);
198
199         btn_hbox = gtk_hbox_new (FALSE, 8);
200         gtk_widget_show (btn_hbox);
201         gtk_box_pack_end (GTK_BOX (vbox), btn_hbox, FALSE, FALSE, 0);
202
203         gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
204                                 &cancel_btn, _("Cancel"), NULL, NULL);
205         gtk_widget_show (confirm_area);
206         gtk_box_pack_end (GTK_BOX(btn_hbox), confirm_area, FALSE, FALSE, 0);
207         gtk_widget_grab_default (ok_btn);
208
209         gtk_window_set_title (GTK_WINDOW(window),
210                               _("Display header setting"));
211         gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
212                             GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
213         gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
214                             GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
215         gtk_signal_connect (GTK_OBJECT(window), "delete_event",
216                             GTK_SIGNAL_FUNC(prefs_display_header_deleted),
217                             NULL);
218         gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
219                             GTK_SIGNAL_FUNC(prefs_display_header_key_pressed),
220                             NULL);
221         gtk_signal_connect (GTK_OBJECT(ok_btn), "clicked",
222                             GTK_SIGNAL_FUNC(prefs_display_header_ok),
223                             NULL);
224         gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
225                             GTK_SIGNAL_FUNC(prefs_display_header_cancel),
226                             NULL);
227
228         vbox1 = gtk_vbox_new (FALSE, VSPACING);
229         gtk_widget_show (vbox1);
230         gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
231         gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
232
233         hbox1 = gtk_hbox_new (FALSE, 8);
234         gtk_widget_show (hbox1);
235         gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, TRUE, 0);
236
237         hdr_label = gtk_label_new (_("Header name"));
238         gtk_widget_show (hdr_label);
239         gtk_box_pack_start (GTK_BOX (hbox1), hdr_label, FALSE, FALSE, 0);
240
241         hdr_combo = gtk_combo_new ();
242         gtk_widget_show (hdr_combo);
243         gtk_box_pack_start (GTK_BOX (hbox1), hdr_combo, TRUE, TRUE, 0);
244         gtk_widget_set_usize (hdr_combo, 150, -1);
245         gtkut_combo_set_items (GTK_COMBO (hdr_combo),
246                                "From", "To", "Cc", "Subject", "Date",
247                                "Reply-To", "Sender", "User-Agent", "X-Mailer",
248                                NULL);
249
250         clist_hbox = gtk_hbox_new (FALSE, 10);
251         gtk_widget_show (clist_hbox);
252         gtk_box_pack_start (GTK_BOX (vbox1), clist_hbox, TRUE, TRUE, 0);
253
254         /* display headers list */
255
256         clist_hbox1 = gtk_hbox_new (FALSE, 8);
257         gtk_widget_show (clist_hbox1);
258         gtk_box_pack_start (GTK_BOX (clist_hbox), clist_hbox1, TRUE, TRUE, 0);
259
260         clist_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
261         gtk_widget_set_usize (clist_scrolledwin, 200, 210);
262         gtk_widget_show (clist_scrolledwin);
263         gtk_box_pack_start (GTK_BOX (clist_hbox1), clist_scrolledwin,
264                             TRUE, TRUE, 0);
265         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clist_scrolledwin),
266                                         GTK_POLICY_AUTOMATIC,
267                                         GTK_POLICY_AUTOMATIC);
268
269         title[0] = _("Displayed Headers");
270         headers_clist = gtk_clist_new_with_titles(1, title);
271         gtk_widget_show (headers_clist);
272         gtk_container_add (GTK_CONTAINER (clist_scrolledwin), headers_clist);
273         gtk_clist_set_selection_mode (GTK_CLIST (headers_clist),
274                                       GTK_SELECTION_BROWSE);
275         gtk_clist_set_reorderable (GTK_CLIST (headers_clist), TRUE);
276         gtk_clist_set_use_drag_icons (GTK_CLIST (headers_clist), FALSE);
277         GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (headers_clist)->column[0].button,
278                                 GTK_CAN_FOCUS);
279         gtk_signal_connect_after
280                 (GTK_OBJECT (headers_clist), "row_move",
281                  GTK_SIGNAL_FUNC (prefs_display_header_row_moved), NULL);
282
283         btn_vbox = gtk_vbox_new (FALSE, 8);
284         gtk_widget_show (btn_vbox);
285         gtk_box_pack_start (GTK_BOX (clist_hbox1), btn_vbox, FALSE, FALSE, 0);
286
287         reg_btn = gtk_button_new_with_label (_("Add"));
288         gtk_widget_show (reg_btn);
289         gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
290         gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
291                             GTK_SIGNAL_FUNC (prefs_display_header_register_cb),
292                             FALSE);
293         del_btn = gtk_button_new_with_label (_("Delete"));
294         gtk_widget_show (del_btn);
295         gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
296         gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
297                             GTK_SIGNAL_FUNC (prefs_display_header_delete_cb),
298                             headers_clist);
299
300         up_btn = gtk_button_new_with_label (_("Up"));
301         gtk_widget_show (up_btn);
302         gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
303         gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
304                             GTK_SIGNAL_FUNC (prefs_display_header_up), NULL);
305
306         down_btn = gtk_button_new_with_label (_("Down"));
307         gtk_widget_show (down_btn);
308         gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
309         gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
310                             GTK_SIGNAL_FUNC (prefs_display_header_down), NULL);
311
312         /* hidden headers list */
313
314         clist_hbox2 = gtk_hbox_new (FALSE, 8);
315         gtk_widget_show (clist_hbox2);
316         gtk_box_pack_start (GTK_BOX (clist_hbox), clist_hbox2, TRUE, TRUE, 0);
317
318         clist_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
319         gtk_widget_set_usize (clist_scrolledwin, 200, 210);
320         gtk_widget_show (clist_scrolledwin);
321         gtk_box_pack_start (GTK_BOX (clist_hbox2), clist_scrolledwin,
322                             TRUE, TRUE, 0);
323         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clist_scrolledwin),
324                                         GTK_POLICY_AUTOMATIC,
325                                         GTK_POLICY_AUTOMATIC);
326
327         title[0] = _("Hidden headers");
328         hidden_headers_clist = gtk_clist_new_with_titles(1, title);
329         gtk_widget_show (hidden_headers_clist);
330         gtk_container_add (GTK_CONTAINER (clist_scrolledwin),
331                            hidden_headers_clist);
332         gtk_clist_set_selection_mode (GTK_CLIST (hidden_headers_clist),
333                                       GTK_SELECTION_BROWSE);
334         gtk_clist_set_auto_sort(GTK_CLIST (hidden_headers_clist), TRUE);
335         GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (hidden_headers_clist)->
336                                 column[0].button, GTK_CAN_FOCUS);
337
338         btn_vbox = gtk_vbox_new (FALSE, 8);
339         gtk_widget_show (btn_vbox);
340         gtk_box_pack_start (GTK_BOX (clist_hbox2), btn_vbox, FALSE, FALSE, 0);
341
342         reg_btn = gtk_button_new_with_label (_("Add"));
343         gtk_widget_show (reg_btn);
344         gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
345         gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
346                             GTK_SIGNAL_FUNC
347                             (prefs_display_header_register_cb),
348                             (void *) TRUE);
349         del_btn = gtk_button_new_with_label (_("Delete"));
350         gtk_widget_show (del_btn);
351         gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
352         gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
353                             GTK_SIGNAL_FUNC (prefs_display_header_delete_cb),
354                             (void *) hidden_headers_clist);
355
356         PACK_CHECK_BUTTON (btn_hbox, checkbtn_other_headers,
357                            _("Show all unspecified headers"));
358         SET_TOGGLE_SENSITIVITY (checkbtn_other_headers, clist_hbox2);
359
360         gtk_widget_show_all(window);
361
362         dispheader.window        = window;
363         dispheader.ok_btn        = ok_btn;
364         dispheader.cancel_btn    = cancel_btn;
365
366         dispheader.hdr_combo     = hdr_combo;
367         dispheader.hdr_entry     = GTK_COMBO (hdr_combo)->entry;
368
369         dispheader.headers_clist        = headers_clist;
370         dispheader.hidden_headers_clist = hidden_headers_clist;
371
372         dispheader.other_headers = checkbtn_other_headers;
373 }
374
375 void prefs_display_header_read_config(void)
376 {
377         gchar *rcpath;
378         FILE *fp;
379         gchar buf[PREFSBUFSIZE];
380         DisplayHeaderProp *dp;
381
382         debug_print(_("Reading configuration for displaying headers...\n"));
383
384         rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
385                              DISPLAY_HEADER_RC, NULL);
386         if ((fp = fopen(rcpath, "r")) == NULL) {
387                 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
388                 g_free(rcpath);
389                 prefs_common.disphdr_list = NULL;
390                 prefs_display_header_set_default();
391                 return;
392         }
393         g_free(rcpath);
394
395         /* remove all previous headers list */
396         while (prefs_common.disphdr_list != NULL) {
397                 dp = (DisplayHeaderProp *)prefs_common.disphdr_list->data;
398                 display_header_prop_free(dp);
399                 prefs_common.disphdr_list =
400                         g_slist_remove(prefs_common.disphdr_list, dp);
401         }
402
403         while (fgets(buf, sizeof(buf), fp) != NULL) {
404                 g_strchomp(buf);
405                 dp = display_header_prop_read_str(buf);
406                 if (dp)
407                         prefs_common.disphdr_list =
408                                 g_slist_append(prefs_common.disphdr_list, dp);
409         }
410
411         fclose(fp);
412 }
413
414 void prefs_display_header_write_config(void)
415 {
416         gchar *rcpath;
417         PrefFile *pfile;
418         GSList *cur;
419
420         debug_print(_("Writing configuration for displaying headers...\n"));
421
422         rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
423                              DISPLAY_HEADER_RC, NULL);
424
425         if ((pfile = prefs_write_open(rcpath)) == NULL) {
426                 g_warning(_("failed to write configuration to file\n"));
427                 g_free(rcpath);
428                 return;
429         }
430
431         for (cur = prefs_common.disphdr_list; cur != NULL;
432              cur = cur->next) {
433                 DisplayHeaderProp *dp = (DisplayHeaderProp *)cur->data;
434                 gchar *dpstr;
435
436                 dpstr = display_header_prop_get_str(dp);
437                 if (fputs(dpstr, pfile->fp) == EOF ||
438                     fputc('\n', pfile->fp) == EOF) {
439                         FILE_OP_ERROR(rcpath, "fputs || fputc");
440                         prefs_write_close_revert(pfile);
441                         g_free(rcpath);
442                         g_free(dpstr);
443                         return;
444                 }
445                 g_free(dpstr);
446         }
447
448         g_free(rcpath);
449
450         if (prefs_write_close(pfile) < 0) {
451                 g_warning(_("failed to write configuration to file\n"));
452                 return;
453         }
454 }
455
456 static void prefs_display_header_set_dialog(void)
457 {
458         GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
459         GtkCList *hidden_clist = GTK_CLIST(dispheader.hidden_headers_clist);
460         GSList *cur;
461         gchar *dp_str[1];
462         gint row;
463
464         gtk_clist_freeze(clist);
465         gtk_clist_freeze(hidden_clist);
466
467         gtk_clist_clear(clist);
468         gtk_clist_clear(hidden_clist);
469
470         for (cur = prefs_common.disphdr_list; cur != NULL;
471              cur = cur->next) {
472                 DisplayHeaderProp *dp = (DisplayHeaderProp *)cur->data;
473
474                 dp_str[0] = dp->name;
475
476                 if (dp->hidden) {
477                         row = gtk_clist_append(hidden_clist, dp_str);
478                         gtk_clist_set_row_data(hidden_clist, row, dp);
479                 } else {
480                         row = gtk_clist_append(clist, dp_str);
481                         gtk_clist_set_row_data(clist, row, dp);
482                 }
483         }
484
485         gtk_clist_thaw(hidden_clist);
486         gtk_clist_thaw(clist);
487
488         gtk_toggle_button_set_active
489                 (GTK_TOGGLE_BUTTON(dispheader.other_headers),
490                  prefs_common.show_other_header);
491 }
492
493 static void prefs_display_header_set_list()
494 {
495         gint row = 0;
496         DisplayHeaderProp *dp;
497
498         g_slist_free(prefs_common.disphdr_list);
499         prefs_common.disphdr_list = NULL;
500
501         while ((dp = gtk_clist_get_row_data
502                 (GTK_CLIST(dispheader.headers_clist), row)) != NULL) {
503                 prefs_common.disphdr_list =
504                         g_slist_append(prefs_common.disphdr_list, dp);
505                 row++;
506         }
507
508         row = 0;
509         while ((dp = gtk_clist_get_row_data
510                 (GTK_CLIST(dispheader.hidden_headers_clist), row)) != NULL) {
511                 prefs_common.disphdr_list =
512                         g_slist_append(prefs_common.disphdr_list, dp);
513                 row++;
514         }
515 }
516
517 static gint prefs_display_header_find_header(GtkCList *clist,
518                                              const gchar *header)
519 {
520         gint row = 0;
521         DisplayHeaderProp *dp;
522
523         while ((dp = gtk_clist_get_row_data(clist, row)) != NULL) {
524                 if (g_strcasecmp(dp->name, header) == 0)
525                         return row;
526                 row++;
527         }
528
529         return -1;
530 }
531
532 static gint prefs_display_header_clist_set_row(gboolean hidden)
533 {
534         GtkCList *clist;
535         DisplayHeaderProp *dp;
536         gchar *entry_text;
537         gchar *dp_str[1];
538         gint row;
539
540         entry_text = gtk_entry_get_text(GTK_ENTRY(dispheader.hdr_entry));
541         if (entry_text[0] == '\0') {
542                 alertpanel_error(_("Header name is not set."));
543                 return -1;
544         }
545
546         if (hidden)
547                 clist = GTK_CLIST(dispheader.hidden_headers_clist);
548         else
549                 clist = GTK_CLIST(dispheader.headers_clist);
550
551         if (prefs_display_header_find_header(clist, entry_text) != -1) {
552                 alertpanel_error(_("This header is already in the list."));
553                 return -1;
554         }
555
556         dp = g_new0(DisplayHeaderProp, 1);
557
558         dp->name = g_strdup(entry_text);
559         dp->hidden = hidden;
560
561         dp_str[0] = dp->name;
562         row = gtk_clist_append(clist, dp_str);
563         gtk_clist_set_row_data(clist, row, dp);
564
565         prefs_display_header_set_list();
566
567         return row;
568 }
569
570 static void prefs_display_header_register_cb(GtkButton *btn,
571                                              gpointer hidden_data)
572 {
573         gboolean hidden = (gboolean)hidden_data;
574
575         prefs_display_header_clist_set_row(hidden);
576 }
577
578 static void prefs_display_header_delete_cb(GtkButton *btn, gpointer clist_data)
579 {
580         GtkCList *clist = GTK_CLIST(clist_data);
581         DisplayHeaderProp *dp;
582         gint row;
583
584         if (!clist->selection) return;
585         row = GPOINTER_TO_INT(clist->selection->data);
586
587         dp = gtk_clist_get_row_data(clist, row);
588         display_header_prop_free(dp);
589         gtk_clist_remove(clist, row);
590         prefs_common.disphdr_list =
591                 g_slist_remove(prefs_common.disphdr_list, dp);
592 }
593
594 static void prefs_display_header_up(void)
595 {
596         GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
597         gint row;
598
599         if (!clist->selection) return;
600
601         row = GPOINTER_TO_INT(clist->selection->data);
602         if (row > 0)
603                 gtk_clist_row_move(clist, row, row - 1);
604 }
605
606 static void prefs_display_header_down(void)
607 {
608         GtkCList *clist = GTK_CLIST(dispheader.headers_clist);
609         gint row;
610
611         if (!clist->selection) return;
612
613         row = GPOINTER_TO_INT(clist->selection->data);
614         if (row >= 0 && row < clist->rows - 1)
615                 gtk_clist_row_move(clist, row, row + 1);
616 }
617
618 static void prefs_display_header_row_moved(GtkCList *clist, gint source_row,
619                                            gint dest_row, gpointer data)
620 {
621         prefs_display_header_set_list();
622 }
623
624 static void prefs_display_header_key_pressed(GtkWidget *widget,
625                                              GdkEventKey *event,
626                                              gpointer data)
627 {
628         if (event && event->keyval == GDK_Escape)
629                 prefs_display_header_cancel();
630 }
631
632 static void prefs_display_header_ok(void)
633 {
634         prefs_common.show_other_header =
635                 gtk_toggle_button_get_active
636                         (GTK_TOGGLE_BUTTON(dispheader.other_headers));
637         prefs_display_header_write_config();
638         gtk_widget_hide(dispheader.window);
639 }
640
641 static void prefs_display_header_cancel(void)
642 {
643         prefs_display_header_read_config();
644         gtk_widget_hide(dispheader.window);
645 }
646
647 static gint prefs_display_header_deleted(GtkWidget *widget, GdkEventAny *event,
648                                          gpointer data)
649 {
650         prefs_display_header_cancel();
651         return TRUE;
652 }