sync with sylpheed 0.4.66cvs3-5
[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 *ok_btn;
52         GtkWidget *cancel_btn;
53
54         GtkWidget *hdr_combo;
55         GtkWidget *hdr_entry;
56 /*      GtkWidget *key_check; */
57         GtkWidget *headers_clist;
58         GtkWidget *hidden_headers_clist;
59
60         GtkWidget *other_headers;
61 } headers;
62
63 /*
64    parameter name, default value, pointer to the prefs variable, data type,
65    pointer to the widget pointer,
66    pointer to the function for data setting,
67    pointer to the function for widget setting
68  */
69
70 #define VSPACING                12
71 #define VSPACING_NARROW         4
72 #define DEFAULT_ENTRY_WIDTH     80
73 #define PREFSBUFSIZE            1024
74
75 /* widget creating functions */
76 static void prefs_display_headers_create        (void);
77
78 static void prefs_display_headers_set_dialog    (void);
79 static void prefs_display_headers_set_list      (void);
80 /* static gint prefs_display_headers_clist_set_row      (gint    row); */
81 static gint prefs_display_headers_clist_set_row(gboolean hidden);
82 /*static gint prefs_display_headers_clist_set_row       (void);*/
83
84 /* callback functions */
85 /*  static void prefs_display_headers_select_dest_cb(void); */
86 static void prefs_display_headers_register_cb(GtkButton *btn,
87                                               void * hidden_data);
88 /*
89 static void prefs_display_headers_register_cb   (void);
90 static void prefs_display_headers_substitute_cb (void);
91 */
92 static void prefs_display_headers_delete_cb(GtkButton *btn, void * clist_data);
93 static void prefs_display_headers_up            (void);
94 static void prefs_display_headers_down          (void);
95 static void prefs_display_headers_select        (GtkCList       *clist,
96                                                  gint            row,
97                                                  gint            column,
98                                                  GdkEvent       *event);
99
100 static void prefs_display_headers_other_headers_toggled(void);
101
102 static void prefs_display_headers_key_pressed   (GtkWidget      *widget,
103                                                  GdkEventKey    *event,
104                                                  gpointer        data);
105 static void prefs_display_headers_ok            (GtkButton      *button);
106 static void prefs_display_headers_cancel        (GtkButton      *button);
107
108 PrefsDisplayHeaders prefs_display_headers = { 1, NULL};
109
110 static gchar *defaults[] =
111 {
112         "Sender",
113         "From",
114         "Reply-To",
115         "To",
116         "Cc",
117         "Subject",
118         "Date",
119         "User-Agent",
120         "X-Mailer",
121         "-Received",
122         "-Message-Id",
123         "-In-Reply-To",
124         "-References",
125         "-Mime-Version",
126         "-Content-Type",
127         "-Content-Transfer-Encoding",
128         "-X-UIDL",
129         "-Precedence",
130         "-Status",
131         "-Priority"
132 };
133
134 static void prefs_display_headers_set_default(void)
135 {
136         int i;
137
138         for(i = 0; i < sizeof(defaults) / sizeof(defaults[0]); i++) {
139                 HeaderDisplayProp *dp =
140                         header_display_prop_read_str(defaults[i]);
141                 prefs_display_headers.headers_list =
142                         g_slist_append(prefs_display_headers.headers_list, dp);
143         }
144 }
145
146 #define ENTRY_SET_TEXT(entry, str) \
147         gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
148
149 void prefs_display_headers_open(void)
150 {
151         if (!headers.window) {
152                 prefs_display_headers_create();
153         }
154
155         manage_window_set_transient(GTK_WINDOW(headers.window));
156         gtk_widget_grab_focus(headers.ok_btn);
157
158         prefs_display_headers_set_dialog();
159
160         gtk_widget_show(headers.window);
161 }
162
163 static void prefs_display_headers_create(void)
164 {
165         GtkWidget *window;
166         GtkWidget *vbox;
167         GtkWidget *ok_btn;
168         GtkWidget *cancel_btn;
169         GtkWidget *confirm_area;
170
171         GtkWidget *vbox1;
172
173         GtkWidget *hbox1;
174         GtkWidget *hdr_label;
175         GtkWidget *hdr_combo;
176 /*      GtkWidget *key_check; */
177
178         GtkWidget *reg_hbox;
179         GtkWidget *btn_hbox;
180         GtkWidget *arrow;
181         GtkWidget *reg_btn;
182 /*      GtkWidget *subst_btn; */
183         GtkWidget *del_btn;
184
185         GtkWidget *ch_hbox;
186         GtkWidget *ch_scrolledwin;
187         GtkWidget *headers_clist;
188         GtkWidget *hidden_headers_clist;
189
190         GtkWidget *btn_vbox;
191         GtkWidget *up_btn;
192         GtkWidget *down_btn;
193
194         GtkWidget *checkbtn_other_headers;
195
196         /*      gchar *title[] = {_("Header name"), _("Action")}; */
197         gchar *title[1];
198
199         debug_print(_("Creating headers setting window...\n"));
200
201         window = gtk_window_new (GTK_WINDOW_DIALOG);
202         gtk_container_set_border_width (GTK_CONTAINER (window), 8);
203         gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
204         gtk_window_set_modal (GTK_WINDOW (window), TRUE);
205         gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
206
207         vbox = gtk_vbox_new (FALSE, 6);
208         gtk_widget_show (vbox);
209         gtk_container_add (GTK_CONTAINER (window), vbox);
210
211         gtkut_button_set_create(&confirm_area, &ok_btn, _("OK"),
212                                 &cancel_btn, _("Cancel"), NULL, NULL);
213         gtk_widget_show (confirm_area);
214         gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
215         gtk_widget_grab_default (ok_btn);
216
217         gtk_window_set_title (GTK_WINDOW(window),
218                               _("Headers setting"));
219         gtk_signal_connect (GTK_OBJECT(window), "delete_event",
220                             GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete), NULL);
221         gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
222                             GTK_SIGNAL_FUNC(prefs_display_headers_key_pressed),
223                             NULL);
224         gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
225                             GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
226         gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
227                             GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
228         gtk_signal_connect (GTK_OBJECT(ok_btn), "clicked",
229                             GTK_SIGNAL_FUNC(prefs_display_headers_ok),
230                             NULL);
231         gtk_signal_connect (GTK_OBJECT(cancel_btn), "clicked",
232                             GTK_SIGNAL_FUNC(prefs_display_headers_cancel),
233                             NULL);
234
235         vbox1 = gtk_vbox_new (FALSE, VSPACING);
236         gtk_widget_show (vbox1);
237         gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
238         gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
239
240         hbox1 = gtk_hbox_new (FALSE, 8);
241         gtk_widget_show (hbox1);
242         gtk_box_pack_start (GTK_BOX (vbox1), hbox1, FALSE, TRUE, 0);
243
244         hdr_label = gtk_label_new (_("Header"));
245         gtk_widget_show (hdr_label);
246         gtk_box_pack_start (GTK_BOX (hbox1), hdr_label, FALSE, FALSE, 0);
247
248         hdr_combo = gtk_combo_new ();
249         gtk_widget_show (hdr_combo);
250         gtk_box_pack_start (GTK_BOX (hbox1), hdr_combo, TRUE, TRUE, 0);
251         gtk_widget_set_usize (hdr_combo, 150 /* 96 */, -1);
252         gtkut_combo_set_items (GTK_COMBO (hdr_combo),
253                                "From", "To", "Subject", "Date", NULL);
254
255 /*      key_check = gtk_check_button_new_with_label(_("Show")); */
256 /*      gtk_widget_show (key_check); */
257 /*      gtk_box_pack_start (GTK_BOX (hbox1), key_check, FALSE, FALSE, 0); */
258 /*      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(key_check), 1); */
259
260         /* register / substitute / delete */
261
262         reg_hbox = gtk_hbox_new (FALSE, 4);
263         gtk_widget_show (reg_hbox);
264         gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox,
265                             FALSE, FALSE, 0);
266
267         arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
268         gtk_widget_show (arrow);
269         gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0);
270         gtk_widget_set_usize (arrow, -1, 16);
271
272         btn_hbox = gtk_hbox_new (TRUE, 4);
273         gtk_widget_show (btn_hbox);
274         gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0);
275
276         /*
277         reg_btn = gtk_button_new_with_label (_("Add"));
278         gtk_widget_show (reg_btn);
279         gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0);
280         gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
281                             GTK_SIGNAL_FUNC
282                             (prefs_display_headers_register_cb), NULL);
283         */
284
285         /*
286         subst_btn = gtk_button_new_with_label (_(" Substitute "));
287         gtk_widget_show (subst_btn);
288         gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0);
289         gtk_signal_connect (GTK_OBJECT (subst_btn), "clicked",
290                             GTK_SIGNAL_FUNC
291                             (prefs_display_headers_substitute_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         title[0] = _("Headers order");
310         headers_clist = gtk_clist_new_with_titles(1, title);
311         gtk_widget_show (headers_clist);
312         gtk_container_add (GTK_CONTAINER (ch_scrolledwin), headers_clist);
313         gtk_clist_set_column_width (GTK_CLIST (headers_clist), 0, 150);
314         /* gtk_clist_set_column_width (GTK_CLIST (headers_clist), 1, 50); */
315         gtk_clist_set_selection_mode (GTK_CLIST (headers_clist),
316                                       GTK_SELECTION_BROWSE);
317         gtk_clist_set_reorderable (GTK_CLIST (headers_clist), TRUE);
318         gtk_clist_set_use_drag_icons (GTK_CLIST (headers_clist), FALSE);
319         GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (headers_clist)->column[0].button,
320                                 GTK_CAN_FOCUS);
321         gtk_signal_connect (GTK_OBJECT (headers_clist), "select_row",
322                             GTK_SIGNAL_FUNC (prefs_display_headers_select),
323                             NULL);
324
325
326         btn_vbox = gtk_vbox_new (FALSE, 8);
327         gtk_widget_show (btn_vbox);
328         gtk_box_pack_start (GTK_BOX (ch_hbox), btn_vbox, FALSE, FALSE, 0);
329
330         reg_btn = gtk_button_new_with_label (_("Add"));
331         gtk_widget_show (reg_btn);
332         gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
333         gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
334                             GTK_SIGNAL_FUNC
335                             (prefs_display_headers_register_cb),
336                             (void *) FALSE);
337         del_btn = gtk_button_new_with_label (_("Delete"));
338         gtk_widget_show (del_btn);
339         gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
340         gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
341                             GTK_SIGNAL_FUNC (prefs_display_headers_delete_cb),
342                             (void *) headers_clist);
343
344         up_btn = gtk_button_new_with_label (_("Up"));
345         gtk_widget_show (up_btn);
346         gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
347         gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
348                             GTK_SIGNAL_FUNC (prefs_display_headers_up), NULL);
349
350         down_btn = gtk_button_new_with_label (_("Down"));
351         gtk_widget_show (down_btn);
352         gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
353         gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
354                             GTK_SIGNAL_FUNC (prefs_display_headers_down), NULL);
355
356         /* hidden headers list */
357
358         ch_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
359         gtk_widget_set_usize (ch_scrolledwin, 230, 200);
360         gtk_widget_show (ch_scrolledwin);
361         gtk_box_pack_start (GTK_BOX (ch_hbox), ch_scrolledwin,
362                             TRUE, TRUE, 0);
363         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (ch_scrolledwin),
364                                         GTK_POLICY_AUTOMATIC,
365                                         GTK_POLICY_AUTOMATIC);
366
367         title[0] = _("Hidden headers");
368         hidden_headers_clist = gtk_clist_new_with_titles(1, title);
369         gtk_widget_show (hidden_headers_clist);
370         gtk_container_add (GTK_CONTAINER (ch_scrolledwin),
371                            hidden_headers_clist);
372         gtk_clist_set_column_width (GTK_CLIST (hidden_headers_clist), 0, 150);
373         gtk_clist_set_selection_mode (GTK_CLIST (hidden_headers_clist),
374                                       GTK_SELECTION_BROWSE);
375         gtk_clist_set_auto_sort(GTK_CLIST (hidden_headers_clist), TRUE);
376         GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (hidden_headers_clist)->
377                                 column[0].button, GTK_CAN_FOCUS);
378         gtk_signal_connect (GTK_OBJECT (hidden_headers_clist), "select_row",
379                             GTK_SIGNAL_FUNC (prefs_display_headers_select),
380                             NULL);
381
382         /* end of hidden headers list */
383
384         btn_vbox = gtk_vbox_new (FALSE, 8);
385         gtk_widget_show (btn_vbox);
386         gtk_box_pack_start (GTK_BOX (ch_hbox), btn_vbox, FALSE, FALSE, 0);
387
388         reg_btn = gtk_button_new_with_label (_("Add"));
389         gtk_widget_show (reg_btn);
390         gtk_box_pack_start (GTK_BOX (btn_vbox), reg_btn, FALSE, TRUE, 0);
391         gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
392                             GTK_SIGNAL_FUNC
393                             (prefs_display_headers_register_cb),
394                             (void *) TRUE);
395         del_btn = gtk_button_new_with_label (_("Delete"));
396         gtk_widget_show (del_btn);
397         gtk_box_pack_start (GTK_BOX (btn_vbox), del_btn, FALSE, TRUE, 0);
398         gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
399                             GTK_SIGNAL_FUNC (prefs_display_headers_delete_cb),
400                             (void *) hidden_headers_clist);
401
402         PACK_CHECK_BUTTON (vbox1, checkbtn_other_headers,
403                            _("Show other headers"));
404         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbtn_other_headers),
405                                      1);
406
407         gtk_signal_connect
408                 (GTK_OBJECT (checkbtn_other_headers), "toggled",
409                  GTK_SIGNAL_FUNC (prefs_display_headers_other_headers_toggled),
410                  NULL);
411
412         gtk_widget_show_all(window);
413
414         headers.window        = window;
415         headers.ok_btn        = ok_btn;
416         headers.cancel_btn    = cancel_btn;
417
418         headers.hdr_combo     = hdr_combo;
419         headers.hdr_entry     = GTK_COMBO (hdr_combo)->entry;
420 /*      headers.key_check     = key_check; */
421         headers.headers_clist = headers_clist;
422         headers.hidden_headers_clist = hidden_headers_clist;
423
424         headers.other_headers = checkbtn_other_headers;
425 }
426
427 void prefs_display_headers_read_config(void)
428 {
429         gchar *rcpath;
430         FILE *fp;
431         gchar buf[PREFSBUFSIZE];
432         HeaderDisplayProp *dp;
433
434         debug_print(_("Reading configuration for displaying of headers...\n"));
435
436         rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
437                              HEADERS_DISPLAY_RC, NULL);
438         if ((fp = fopen(rcpath, "r")) == NULL) {
439                 if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
440                 g_free(rcpath);
441                 prefs_display_headers.headers_list = NULL;
442                 prefs_display_headers_set_default();
443                 return;
444         }
445         g_free(rcpath);
446
447         /* remove all previous headers list */
448         while (prefs_display_headers.headers_list != NULL) {
449                 dp = (HeaderDisplayProp *)
450                         prefs_display_headers.headers_list->data;
451                 header_display_prop_free(dp);
452                 prefs_display_headers.headers_list =
453                         g_slist_remove(prefs_display_headers.headers_list, dp);
454         }
455
456         prefs_display_headers.show_other_headers = 1;
457  
458         while (fgets(buf, sizeof(buf), fp) != NULL) {
459                 g_strchomp(buf);
460                 if (strcmp(buf, "-") == 0)
461                         prefs_display_headers.show_other_headers = 0;
462                 else {
463                         dp = header_display_prop_read_str(buf);
464                         if (dp)
465                                 prefs_display_headers.headers_list =
466                                         g_slist_append(prefs_display_headers.headers_list, dp);
467                 }
468         }
469  
470         fclose(fp);
471 }
472
473 void prefs_display_headers_write_config(void)
474 {
475         gchar *rcpath;
476         PrefFile *pfile;
477         GSList *cur;
478 /*      gchar buf[PREFSBUFSIZE]; */
479 /*      FILE *fp; */
480 /*      HeaderDisplayProp *dp; */
481
482         debug_print(_("Writing configuration for displaying of headers...\n"));
483
484         rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
485                              HEADERS_DISPLAY_RC, NULL);
486
487         if ((pfile = prefs_write_open(rcpath)) == NULL) {
488                 g_warning(_("failed to write configuration to file\n"));
489                 g_free(rcpath);
490                 return;
491         }
492
493         for (cur = prefs_display_headers.headers_list; cur != NULL;
494              cur = cur->next) {
495                 HeaderDisplayProp *hdr = (HeaderDisplayProp *)cur->data;
496                 gchar *dpstr;
497
498                 dpstr = header_display_prop_get_str(hdr);
499                 if (fputs(dpstr, pfile->fp) == EOF ||
500                     fputc('\n', pfile->fp) == EOF) {
501                         FILE_OP_ERROR(rcpath, "fputs || fputc");
502                         prefs_write_close_revert(pfile);
503                         g_free(rcpath);
504                         g_free(dpstr);
505                         return;
506                 }
507                 g_free(dpstr);
508         }
509
510         if (!prefs_display_headers.show_other_headers) {
511                 if (fputs("-\n", pfile->fp) == EOF) {
512                         FILE_OP_ERROR(rcpath, "fputs");
513                         prefs_write_close_revert(pfile);
514                         g_free(rcpath);
515                         return;
516                 }
517         }
518
519         g_free(rcpath);
520
521         if (prefs_write_close(pfile) < 0) {
522                 g_warning(_("failed to write configuration to file\n"));
523                 return;
524         }
525 }
526
527 static void prefs_display_headers_set_dialog()
528 {
529         GtkCList * clist = GTK_CLIST(headers.headers_clist);
530         GtkCList * hidden_clist = GTK_CLIST(headers.hidden_headers_clist);
531         GSList *cur;
532         gchar *dp_str[1];
533         gint row;
534
535         gtk_clist_freeze(clist);
536         gtk_clist_clear(clist);
537
538         gtk_clist_freeze(hidden_clist);
539         gtk_clist_clear(hidden_clist);
540
541 /*      dp_str[0] = _("(New)"); */
542
543 /*      row = gtk_clist_append(clist, dp_str); */
544 /*      gtk_clist_set_row_data(clist, row, NULL); */
545
546 /*      row = gtk_clist_append(hidden_clist, dp_str); */
547 /*      gtk_clist_set_row_data(hidden_clist, row, NULL); */
548
549         for (cur = prefs_display_headers.headers_list; cur != NULL;
550              cur = cur->next) {
551                 HeaderDisplayProp *dp = (HeaderDisplayProp *)cur->data;
552
553                 dp_str[0] = dp->name;
554                 /* dp_str[1] = dp->hidden ? _("Hide") : _("Show"); */
555
556                 if (dp->hidden) {
557                         row = gtk_clist_append(hidden_clist, dp_str);
558                         gtk_clist_set_row_data(hidden_clist, row, dp);
559                 }
560                 else {
561                         row = gtk_clist_append(clist, dp_str);
562                         gtk_clist_set_row_data(clist, row, dp);
563                 }
564         }
565
566         gtk_clist_thaw(hidden_clist);
567         gtk_clist_thaw(clist);
568
569         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(headers.other_headers), prefs_display_headers.show_other_headers);
570 }
571
572 static void prefs_display_headers_set_list()
573 {
574         gint row;
575         HeaderDisplayProp *dp;
576
577         g_slist_free(prefs_display_headers.headers_list);
578         prefs_display_headers.headers_list = NULL;
579
580         row = 0;
581         while ((dp = gtk_clist_get_row_data(GTK_CLIST(headers.headers_clist),
582                 row)) != NULL) {
583                 prefs_display_headers.headers_list =
584                         g_slist_append(prefs_display_headers.headers_list, dp);
585                 row++;
586         }
587
588         row = 0;
589         while ((dp = gtk_clist_get_row_data(GTK_CLIST(headers.hidden_headers_clist), row)) != NULL) {
590                 prefs_display_headers.headers_list =
591                         g_slist_append(prefs_display_headers.headers_list, dp);
592                 row++;
593         }
594 }
595
596 /**
597  * prefs_display_headers_find_header:
598  * @clist: List of headers.
599  * @header: Header name.
600  * 
601  * Find row of @clist which contains @header.
602  * 
603  * Return value: Row index, or -1 if not found.
604  **/
605 static gint prefs_display_headers_find_header(GtkCList *clist,
606                                               const gchar *header)
607 {
608         gint row;
609         HeaderDisplayProp *dp;
610
611         row = 0;
612         while ((dp = gtk_clist_get_row_data(clist, row)) != NULL) {
613                 if (g_strcasecmp(dp->name, header) == 0)
614                         return row;
615                 row++;
616         }
617         return -1;
618 }
619
620 #define GET_ENTRY(entry) \
621         entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
622
623 static gint prefs_display_headers_clist_set_row(gboolean hidden)
624 {
625         GtkCList *clist;
626         HeaderDisplayProp *dp;
627         gchar *entry_text;
628         gchar *dp_str[1];
629         gint row;
630
631         GET_ENTRY(headers.hdr_entry);
632         if (entry_text[0] == '\0') {
633                 alertpanel_error(_("Header name is not set."));
634                 return -1;
635         }
636
637         if (hidden)
638                 clist = GTK_CLIST(headers.hidden_headers_clist);
639         else
640                 clist = GTK_CLIST(headers.headers_clist);
641
642         if (prefs_display_headers_find_header(clist, entry_text) != -1) {
643                 alertpanel_error(_("This header is already in the list."));
644                 return -1;
645         }
646
647         dp = g_new0(HeaderDisplayProp, 1);
648
649         dp->name = g_strdup(entry_text);
650
651         /*
652         dp->hidden = !gtk_toggle_button_get_active
653                 (GTK_TOGGLE_BUTTON(headers.key_check));
654         */
655         dp->hidden = hidden;
656
657         dp_str[0] = dp->name;
658
659         row = gtk_clist_append(clist, dp_str);
660         
661         gtk_clist_set_row_data(clist, row, dp);
662         
663         prefs_display_headers_set_list();
664                 
665         return row;
666 }
667
668 static void prefs_display_headers_register_cb(GtkButton *btn,
669                                               void * hidden_data)
670 {
671         gboolean hidden = (gboolean) hidden_data;
672
673         prefs_display_headers_clist_set_row(hidden);
674 }
675
676 /*
677 static void prefs_display_headers_substitute_cb(void)
678 {
679         GtkCList *clist = GTK_CLIST(headers.headers_clist);
680         HeaderDisplayProp *dp;
681         gint row;
682
683         if (!clist->selection) return;
684
685         row = GPOINTER_TO_INT(clist->selection->data);
686         if (row == 0) return;
687
688         dp = gtk_clist_get_row_data(clist, row);
689         if (!dp) return;
690
691         prefs_display_headers_clist_set_row(row);
692 }
693 */
694
695 static void prefs_display_headers_delete_cb(GtkButton *btn, void * clist_data)
696 {
697         //      GtkCList *clist = GTK_CLIST(headers.headers_clist);     
698         GtkCList *clist = GTK_CLIST(clist_data);
699         HeaderDisplayProp *dp;
700         gint row;
701
702         if (!clist->selection) return;
703         row = GPOINTER_TO_INT(clist->selection->data);
704 /*      if (row == 0) return; */
705
706         if (alertpanel(_("Delete header"),
707                        _("Do you really want to delete this header?"),
708                        _("Yes"), _("No"), NULL) != G_ALERTDEFAULT)
709                 return;
710
711         dp = gtk_clist_get_row_data(clist, row);
712         header_display_prop_free(dp);
713         gtk_clist_remove(clist, row);
714         prefs_display_headers.headers_list =
715                 g_slist_remove(prefs_display_headers.headers_list, dp);
716 }
717
718 static void prefs_display_headers_up(void)
719 {
720         GtkCList *clist = GTK_CLIST(headers.headers_clist);
721         gint row;
722
723         if (!clist->selection) return;
724
725         row = GPOINTER_TO_INT(clist->selection->data);
726         if (row > 0) {
727                 gtk_clist_row_move(clist, row, row - 1);
728                 prefs_display_headers_set_list();
729         }
730 }
731
732 static void prefs_display_headers_down(void)
733 {
734         GtkCList *clist = GTK_CLIST(headers.headers_clist);
735         gint row;
736
737         if (!clist->selection) return;
738
739         row = GPOINTER_TO_INT(clist->selection->data);
740         if (row >= 0 && row < clist->rows - 1) {
741                 gtk_clist_row_move(clist, row, row + 1);
742                 prefs_display_headers_set_list();
743         }
744 }
745
746 static void prefs_display_headers_select(GtkCList *clist, gint row,
747                                          gint column, GdkEvent *event)
748 {
749         HeaderDisplayProp *dp;
750         HeaderDisplayProp default_dp = { "", 0 };
751
752         dp = gtk_clist_get_row_data(clist, row);
753         if (!dp)
754                 dp = &default_dp;
755
756         ENTRY_SET_TEXT(headers.hdr_entry, "");
757
758         /*      ENTRY_SET_TEXT(headers.hdr_entry, dp->name);
759         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(headers.key_check),
760         !dp->hidden);*/
761
762         /*
763         if ((row != 0) && event && (event->type == GDK_2BUTTON_PRESS)) {
764                 gtk_toggle_button_set_active
765                         (GTK_TOGGLE_BUTTON(headers.key_check), dp->hidden);
766                 prefs_display_headers_clist_set_row(row);
767         }
768         */
769 }
770
771 static void prefs_display_headers_key_pressed(GtkWidget *widget,
772                                               GdkEventKey *event,
773                                               gpointer data)
774 {
775         if (event && event->keyval == GDK_Escape)
776                 gtk_widget_hide(headers.window);
777 }
778
779 static void prefs_display_headers_ok(GtkButton *button)
780 {
781         prefs_display_headers_write_config();
782         gtk_widget_hide(headers.window);
783 }
784
785 static void prefs_display_headers_cancel(GtkButton *button)
786 {
787         prefs_display_headers_read_config();
788         gtk_widget_hide(headers.window);
789 }
790
791 static void prefs_display_headers_other_headers_toggled(void)
792 {
793         prefs_display_headers.show_other_headers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(headers.other_headers));
794 }