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