custom headers configuration added
authorHoà Viêt Dinh <dinh.viet.hoa@free.fr>
Tue, 24 Apr 2001 15:44:45 +0000 (15:44 +0000)
committerHoà Viêt Dinh <dinh.viet.hoa@free.fr>
Tue, 24 Apr 2001 15:44:45 +0000 (15:44 +0000)
12 files changed:
ChangeLog.claws
config.h.in
src/Makefile.am
src/Makefile.in
src/compose.c
src/defs.h
src/headers.c [new file with mode: 0644]
src/headers.h [new file with mode: 0644]
src/prefs_account.c
src/prefs_account.h
src/prefs_headers.c [new file with mode: 0644]
src/prefs_headers.h [new file with mode: 0644]

index 21add5041439cae46c3fef1d1899b5effb33ec85..3fc693e1b04b396fbe4c61bca45cfeb3b7f36a3f 100644 (file)
@@ -1,5 +1,14 @@
 2001-04-24
        * added comments in src/news.c src/nntp.c
 2001-04-24
        * added comments in src/news.c src/nntp.c
+       * added src/prefs_headers.[ch]
+       * added src/headers.[ch]
+       * modified compose.c to activate custom headers
+               added function is_in_custom_headers
+       * modified prefs_account.[ch]
+               added function prefs_account_customhdr_edit
+       * modified src/defs.h :
+               added HEADERS_RC : name of the config file
+               for the custom headers
 
 2001-04-24
 
 
 2001-04-24
 
index 8113c4f9bd9d9e13427f817df6ec1b2f2fca7c73..6770245093f73a6be54175f078e46e12115992fb 100644 (file)
@@ -31,9 +31,6 @@
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #undef pid_t
 
 /* Define to `int' if <sys/types.h> doesn't define.  */
 #undef pid_t
 
-/* Define if you need to in order for stat and other things to work.  */
-#undef _POSIX_SOURCE
-
 /* Define to `unsigned' if <sys/types.h> doesn't define.  */
 #undef size_t
 
 /* Define to `unsigned' if <sys/types.h> doesn't define.  */
 #undef size_t
 
 /* Define if your <sys/time.h> declares struct tm.  */
 #undef TM_IN_SYS_TIME
 
 /* Define if your <sys/time.h> declares struct tm.  */
 #undef TM_IN_SYS_TIME
 
-#undef ENABLE_NLS
-#undef HAVE_CATGETS
-#undef HAVE_GETTEXT
-#undef HAVE_LC_MESSAGES
-#undef HAVE_STPCPY
-
 #undef HAVE_GDK_PIXBUF
 #undef HAVE_GDK_IMLIB
 
 #undef HAVE_GDK_PIXBUF
 #undef HAVE_GDK_IMLIB
 
 /* Define if you have the fchmod function.  */
 #undef HAVE_FCHMOD
 
 /* Define if you have the fchmod function.  */
 #undef HAVE_FCHMOD
 
+/* Define if you have the feof_unlocked function.  */
+#undef HAVE_FEOF_UNLOCKED
+
+/* Define if you have the fgets_unlocked function.  */
+#undef HAVE_FGETS_UNLOCKED
+
 /* Define if you have the flock function.  */
 #undef HAVE_FLOCK
 
 /* Define if you have the flock function.  */
 #undef HAVE_FLOCK
 
 /* Define if you have the lockf function.  */
 #undef HAVE_LOCKF
 
 /* Define if you have the lockf function.  */
 #undef HAVE_LOCKF
 
+/* Define if you have the mempcpy function.  */
+#undef HAVE_MEMPCPY
+
 /* Define if you have the mkdir function.  */
 #undef HAVE_MKDIR
 
 /* Define if you have the mkdir function.  */
 #undef HAVE_MKDIR
 
 /* Define if you have the towlower function.  */
 #undef HAVE_TOWLOWER
 
 /* Define if you have the towlower function.  */
 #undef HAVE_TOWLOWER
 
+/* Define if you have the tsearch function.  */
+#undef HAVE_TSEARCH
+
 /* Define if you have the uname function.  */
 #undef HAVE_UNAME
 
 /* Define if you have the uname function.  */
 #undef HAVE_UNAME
 
 /* Define if you have the <paths.h> header file.  */
 #undef HAVE_PATHS_H
 
 /* Define if you have the <paths.h> header file.  */
 #undef HAVE_PATHS_H
 
+/* Define if you have the <stddef.h> header file.  */
+#undef HAVE_STDDEF_H
+
+/* Define if you have the <stdlib.h> header file.  */
+#undef HAVE_STDLIB_H
+
 /* Define if you have the <string.h> header file.  */
 #undef HAVE_STRING_H
 
 /* Define if you have the <string.h> header file.  */
 #undef HAVE_STRING_H
 
 /* Define if you have the compface library (-lcompface).  */
 #undef HAVE_LIBCOMPFACE
 
 /* Define if you have the compface library (-lcompface).  */
 #undef HAVE_LIBCOMPFACE
 
-/* Define if you have the i library (-li).  */
-#undef HAVE_LIBI
-
 /* Define if you have the jconv library (-ljconv).  */
 #undef HAVE_LIBJCONV
 
 /* Define if you have the xpg4 library (-lxpg4).  */
 #undef HAVE_LIBXPG4
 /* Define if you have the jconv library (-ljconv).  */
 #undef HAVE_LIBJCONV
 
 /* Define if you have the xpg4 library (-lxpg4).  */
 #undef HAVE_LIBXPG4
+
+/* Define if you have the iconv() function. */
+#undef HAVE_ICONV
+
+/* Define as const if the declaration of iconv() needs const. */
+#undef ICONV_CONST
+
+/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
+#undef HAVE_LANGINFO_CODESET
+
+/* Define if your <locale.h> file defines LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if translation of program messages to the user's native language
+   is requested. */
+#undef ENABLE_NLS
+
+/* Define if the GNU gettext() function is already present or preinstalled. */
+#undef HAVE_GETTEXT
+
index b8032f45239bca74583be922c0c9c1e5cb4055c5..c2afea1cea582ebadcd5c202bc1009255ee9a90d 100644 (file)
@@ -73,7 +73,9 @@ sylpheed_SOURCES = \
        addr_compl.c addr_compl.h \
        export.c export.h \
        gtkstext.c gtkstext.h \
        addr_compl.c addr_compl.h \
        export.c export.h \
        gtkstext.c gtkstext.h \
-       grouplist_dialog.c grouplist_dialog.h
+       grouplist_dialog.c grouplist_dialog.h \
+       headers.c headers.h \
+       prefs_headers.c prefs_header.h
 
 EXTRA_DIST = \
        pixmaps/clip.xpm \
 
 EXTRA_DIST = \
        pixmaps/clip.xpm \
index 7bd3e919e78f8afc356f399ba5ec88f7231a6c23..49206a6b33a864e66abe57e0daaf7c1ecefd5743 100644 (file)
@@ -114,7 +114,7 @@ manualdir = @manualdir@
 
 bin_PROGRAMS = sylpheed
 
 
 bin_PROGRAMS = sylpheed
 
-sylpheed_SOURCES =     intl.h  defs.h  main.c main.h   mainwindow.c mainwindow.h       folderview.c folderview.h       summaryview.c summaryview.h     messageview.c messageview.h     headerview.c headerview.h       textview.c textview.h   imageview.c imageview.h         mimeview.c mimeview.h   summary_search.c summary_search.h       folder.c folder.h       procmsg.c procmsg.h     procheader.c procheader.h       filter.c filter.h       compose.c compose.h     gtkshruler.c gtkshruler.h       gtksctree.c gtksctree.h         menu.c menu.h   prefs.c prefs.h         prefs_common.c prefs_common.h   prefs_filter.c prefs_filter.h   prefs_account.c prefs_account.h         account.c account.h     addressbook.c addressbook.h     filesel.c filesel.h     foldersel.c foldersel.h         statusbar.c statusbar.h         headerwindow.c headerwindow.h   logwindow.c logwindow.h         sourcewindow.c sourcewindow.h   manage_window.c manage_window.h         alertpanel.c alertpanel.h       inputdialog.c inputdialog.h     progressdialog.c progressdialog.h       about.c about.h         setup.c setup.h         utils.c utils.h         gtkutils.c gtkutils.h   codeconv.c codeconv.h   unmime.c unmime.h       base64.c base64.h       uuencode.c uuencode.h   md5c.c md5.h md5global.h        md5ify.c md5ify.h       rfc822.c rfc822.h       socket.c socket.h       automaton.c automaton.h         session.c session.h     smtp.c smtp.h   esmtp.c esmtp.h         pop.c pop.h     mh.c mh.h       mbox.c mbox.h   send.c send.h   recv.c recv.h   inc.c inc.h     import.c import.h       nntp.c nntp.h   news.c news.h   imap.c imap.h   xml.c xml.h     html.c html.h   procmime.c procmime.h   rfc2015.c rfc2015.h     passphrase.c passphrase.h       select-keys.c select-keys.h     manual.c manual.h       addr_compl.c addr_compl.h       export.c export.h       grouplist_dialog.c grouplist_dialog.h
+sylpheed_SOURCES =     intl.h  defs.h  main.c main.h   mainwindow.c mainwindow.h       folderview.c folderview.h       summaryview.c summaryview.h     messageview.c messageview.h     headerview.c headerview.h       textview.c textview.h   imageview.c imageview.h         mimeview.c mimeview.h   summary_search.c summary_search.h       folder.c folder.h       procmsg.c procmsg.h     procheader.c procheader.h       filter.c filter.h       compose.c compose.h     gtkshruler.c gtkshruler.h       gtksctree.c gtksctree.h         menu.c menu.h   prefs.c prefs.h         prefs_common.c prefs_common.h   prefs_filter.c prefs_filter.h   prefs_account.c prefs_account.h         account.c account.h     addressbook.c addressbook.h     filesel.c filesel.h     foldersel.c foldersel.h         statusbar.c statusbar.h         headerwindow.c headerwindow.h   logwindow.c logwindow.h         sourcewindow.c sourcewindow.h   manage_window.c manage_window.h         alertpanel.c alertpanel.h       inputdialog.c inputdialog.h     progressdialog.c progressdialog.h       about.c about.h         setup.c setup.h         utils.c utils.h         gtkutils.c gtkutils.h   codeconv.c codeconv.h   unmime.c unmime.h       base64.c base64.h       uuencode.c uuencode.h   md5c.c md5.h md5global.h        md5ify.c md5ify.h       rfc822.c rfc822.h       socket.c socket.h       automaton.c automaton.h         session.c session.h     smtp.c smtp.h   esmtp.c esmtp.h         pop.c pop.h     mh.c mh.h       mbox.c mbox.h   send.c send.h   recv.c recv.h   inc.c inc.h     import.c import.h       nntp.c nntp.h   news.c news.h   imap.c imap.h   xml.c xml.h     html.c html.h   procmime.c procmime.h   rfc2015.c rfc2015.h     passphrase.c passphrase.h       select-keys.c select-keys.h     manual.c manual.h       addr_compl.c addr_compl.h       export.c export.h       gtkstext.c gtkstext.h   grouplist_dialog.c grouplist_dialog.h   headers.c headers.h     prefs_headers.c prefs_header.h
 
 
 EXTRA_DIST =   pixmaps/clip.xpm        pixmaps/deleted.xpm     pixmaps/dir-close.xpm   pixmaps/dir-open.xpm    pixmaps/folder.xpm      pixmaps/forwarded.xpm   pixmaps/group.xpm       pixmaps/inbox.xpm       pixmaps/mark.xpm        pixmaps/new.xpm         pixmaps/outbox.xpm      pixmaps/regular.xpm     pixmaps/replied.xpm     pixmaps/trash.xpm       pixmaps/unread.xpm      pixmaps/linewrap.xpm    pixmaps/stock_mail.xpm  pixmaps/stock_mail_attach.xpm   pixmaps/stock_mail_receive.xpm  pixmaps/stock_mail_receive_all.xpm      pixmaps/stock_mail_send.xpm     pixmaps/stock_mail_compose.xpm  pixmaps/stock_mail_reply.xpm    pixmaps/stock_mail_reply_to_all.xpm     pixmaps/stock_mail_forward.xpm  pixmaps/stock_preferences.xpm   pixmaps/stock_properties.xpm    pixmaps/stock_search.xpm        pixmaps/stock_close.xpm         pixmaps/stock_exec.xpm  pixmaps/stock_trash.xpm         pixmaps/stock_up_arrow.xpm      pixmaps/stock_down_arrow.xpm    pixmaps/stock_paste.xpm         pixmaps/tb_address_book.xpm     pixmaps/sylpheed-logo.xpm
 
 
 EXTRA_DIST =   pixmaps/clip.xpm        pixmaps/deleted.xpm     pixmaps/dir-close.xpm   pixmaps/dir-open.xpm    pixmaps/folder.xpm      pixmaps/forwarded.xpm   pixmaps/group.xpm       pixmaps/inbox.xpm       pixmaps/mark.xpm        pixmaps/new.xpm         pixmaps/outbox.xpm      pixmaps/regular.xpm     pixmaps/replied.xpm     pixmaps/trash.xpm       pixmaps/unread.xpm      pixmaps/linewrap.xpm    pixmaps/stock_mail.xpm  pixmaps/stock_mail_attach.xpm   pixmaps/stock_mail_receive.xpm  pixmaps/stock_mail_receive_all.xpm      pixmaps/stock_mail_send.xpm     pixmaps/stock_mail_compose.xpm  pixmaps/stock_mail_reply.xpm    pixmaps/stock_mail_reply_to_all.xpm     pixmaps/stock_mail_forward.xpm  pixmaps/stock_preferences.xpm   pixmaps/stock_properties.xpm    pixmaps/stock_search.xpm        pixmaps/stock_close.xpm         pixmaps/stock_exec.xpm  pixmaps/stock_trash.xpm         pixmaps/stock_up_arrow.xpm      pixmaps/stock_down_arrow.xpm    pixmaps/stock_paste.xpm         pixmaps/tb_address_book.xpm     pixmaps/sylpheed-logo.xpm
@@ -148,7 +148,7 @@ gtkutils.o codeconv.o unmime.o base64.o uuencode.o md5c.o md5ify.o \
 rfc822.o socket.o automaton.o session.o smtp.o esmtp.o pop.o mh.o \
 mbox.o send.o recv.o inc.o import.o nntp.o news.o imap.o xml.o html.o \
 procmime.o rfc2015.o passphrase.o select-keys.o manual.o addr_compl.o \
 rfc822.o socket.o automaton.o session.o smtp.o esmtp.o pop.o mh.o \
 mbox.o send.o recv.o inc.o import.o nntp.o news.o imap.o xml.o html.o \
 procmime.o rfc2015.o passphrase.o select-keys.o manual.o addr_compl.o \
-export.o grouplist_dialog.o
+export.o gtkstext.o grouplist_dialog.o headers.o prefs_headers.o
 sylpheed_DEPENDENCIES =  $(top_builddir)/libkcc/libkcc.a
 sylpheed_LDFLAGS = 
 CFLAGS = @CFLAGS@
 sylpheed_DEPENDENCIES =  $(top_builddir)/libkcc/libkcc.a
 sylpheed_LDFLAGS = 
 CFLAGS = @CFLAGS@
@@ -168,20 +168,21 @@ DEP_FILES =  .deps/about.P .deps/account.P .deps/addr_compl.P \
 .deps/codeconv.P .deps/compose.P .deps/esmtp.P .deps/export.P \
 .deps/filesel.P .deps/filter.P .deps/folder.P .deps/foldersel.P \
 .deps/folderview.P .deps/grouplist_dialog.P .deps/gtksctree.P \
 .deps/codeconv.P .deps/compose.P .deps/esmtp.P .deps/export.P \
 .deps/filesel.P .deps/filter.P .deps/folder.P .deps/foldersel.P \
 .deps/folderview.P .deps/grouplist_dialog.P .deps/gtksctree.P \
-.deps/gtkshruler.P .deps/gtkutils.P .deps/headerview.P \
-.deps/headerwindow.P .deps/html.P .deps/imageview.P .deps/imap.P \
-.deps/import.P .deps/inc.P .deps/inputdialog.P .deps/logwindow.P \
-.deps/main.P .deps/mainwindow.P .deps/manage_window.P .deps/manual.P \
-.deps/mbox.P .deps/md5c.P .deps/md5ify.P .deps/menu.P \
+.deps/gtkshruler.P .deps/gtkstext.P .deps/gtkutils.P .deps/headers.P \
+.deps/headerview.P .deps/headerwindow.P .deps/html.P .deps/imageview.P \
+.deps/imap.P .deps/import.P .deps/inc.P .deps/inputdialog.P \
+.deps/logwindow.P .deps/main.P .deps/mainwindow.P .deps/manage_window.P \
+.deps/manual.P .deps/mbox.P .deps/md5c.P .deps/md5ify.P .deps/menu.P \
 .deps/messageview.P .deps/mh.P .deps/mimeview.P .deps/news.P \
 .deps/nntp.P .deps/passphrase.P .deps/pop.P .deps/prefs.P \
 .deps/prefs_account.P .deps/prefs_common.P .deps/prefs_filter.P \
 .deps/messageview.P .deps/mh.P .deps/mimeview.P .deps/news.P \
 .deps/nntp.P .deps/passphrase.P .deps/pop.P .deps/prefs.P \
 .deps/prefs_account.P .deps/prefs_common.P .deps/prefs_filter.P \
-.deps/procheader.P .deps/procmime.P .deps/procmsg.P \
-.deps/progressdialog.P .deps/recv.P .deps/rfc2015.P .deps/rfc822.P \
-.deps/select-keys.P .deps/send.P .deps/session.P .deps/setup.P \
-.deps/smtp.P .deps/socket.P .deps/sourcewindow.P .deps/statusbar.P \
-.deps/summary_search.P .deps/summaryview.P .deps/textview.P \
-.deps/unmime.P .deps/utils.P .deps/uuencode.P .deps/xml.P
+.deps/prefs_headers.P .deps/procheader.P .deps/procmime.P \
+.deps/procmsg.P .deps/progressdialog.P .deps/recv.P .deps/rfc2015.P \
+.deps/rfc822.P .deps/select-keys.P .deps/send.P .deps/session.P \
+.deps/setup.P .deps/smtp.P .deps/socket.P .deps/sourcewindow.P \
+.deps/statusbar.P .deps/summary_search.P .deps/summaryview.P \
+.deps/textview.P .deps/unmime.P .deps/utils.P .deps/uuencode.P \
+.deps/xml.P
 SOURCES = $(sylpheed_SOURCES)
 OBJECTS = $(sylpheed_OBJECTS)
 
 SOURCES = $(sylpheed_SOURCES)
 OBJECTS = $(sylpheed_OBJECTS)
 
index 47b41e0ff7d46e51c9b0cf231d3ac030fe37cc52..4fe9745df1e1fa829d113c906fdb339cad62bd2b 100644 (file)
@@ -97,6 +97,7 @@
 #include "gtkshruler.h"
 #include "folder.h"
 #include "addr_compl.h"
 #include "gtkshruler.h"
 #include "folder.h"
 #include "addr_compl.h"
+#include "headers.h"
 
 #if USE_GPGME
 #  include "rfc2015.h"
 
 #if USE_GPGME
 #  include "rfc2015.h"
@@ -1857,6 +1858,21 @@ static void compose_write_attach(Compose *compose, FILE *fp)
        fprintf(fp, "\n--%s--\n", compose->boundary);
 }
 
        fprintf(fp, "\n--%s--\n", compose->boundary);
 }
 
+static gint is_in_custom_headers(Compose *compose, gchar * header)
+{
+       GSList * cur;
+
+       if (compose->account->add_customhdr) {
+               for (cur = compose->account->customhdr_list;
+                    cur != NULL; cur = cur->next) {
+                       CustomHeader * ch = (CustomHeader *) cur->data;
+                       if (strcasecmp(ch->name, header) == 0)
+                               return 1;
+               }
+       }
+       return 0;
+}
+
 static gint compose_write_headers(Compose *compose, FILE *fp,
                                  const gchar *charset, EncodingType encoding,
                                  gboolean is_draft)
 static gint compose_write_headers(Compose *compose, FILE *fp,
                                  const gchar *charset, EncodingType encoding,
                                  gboolean is_draft)
@@ -1864,6 +1880,7 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
        gchar buf[BUFFSIZE];
        gchar *str;
        /* struct utsname utsbuf; */
        gchar buf[BUFFSIZE];
        gchar *str;
        /* struct utsname utsbuf; */
+       GSList * cur;
 
        g_return_val_if_fail(fp != NULL, -1);
        g_return_val_if_fail(charset != NULL, -1);
 
        g_return_val_if_fail(fp != NULL, -1);
        g_return_val_if_fail(charset != NULL, -1);
@@ -1871,19 +1888,23 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
        g_return_val_if_fail(compose->account->address != NULL, -1);
 
        /* Date */
        g_return_val_if_fail(compose->account->address != NULL, -1);
 
        /* Date */
-       if (compose->account->add_date) {
-               get_rfc822_date(buf, sizeof(buf));
-               fprintf(fp, "Date: %s\n", buf);
+       if (!is_in_custom_headers(compose, "Date")) {
+               if (compose->account->add_date) {
+                       get_rfc822_date(buf, sizeof(buf));
+                       fprintf(fp, "Date: %s\n", buf);
+               }
        }
 
        /* From */
        }
 
        /* From */
-       if (compose->account->name && *compose->account->name) {
-               compose_convert_header
-                       (buf, sizeof(buf), compose->account->name,
-                        strlen("From: "));
-               fprintf(fp, "From: %s <%s>\n", buf, compose->account->address);
-       } else
-               fprintf(fp, "From: %s\n", compose->account->address);
+       if (!is_in_custom_headers(compose, "From")) {
+               if (compose->account->name && *compose->account->name) {
+                       compose_convert_header
+                               (buf, sizeof(buf), compose->account->name,
+                                strlen("From: "));
+                       fprintf(fp, "From: %s <%s>\n", buf, compose->account->address);
+               } else
+                       fprintf(fp, "From: %s\n", compose->account->address);
+       }
 
        slist_free_strings(compose->to_list);
        g_slist_free(compose->to_list);
 
        slist_free_strings(compose->to_list);
        g_slist_free(compose->to_list);
@@ -1900,7 +1921,9 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
                                        (compose->to_list, str);
                                compose_convert_header(buf, sizeof(buf), str,
                                                       strlen("To: "));
                                        (compose->to_list, str);
                                compose_convert_header(buf, sizeof(buf), str,
                                                       strlen("To: "));
-                               fprintf(fp, "To: %s\n", buf);
+                               if (!is_in_custom_headers(compose, "To")) {
+                                       fprintf(fp, "To: %s\n", buf);
+                               }
                        }
                }
        }
                        }
                }
        }
@@ -1921,7 +1944,9 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
                                                      str);
                        compose_convert_header(buf, sizeof(buf), str,
                                               strlen("Newsgroups: "));
                                                      str);
                        compose_convert_header(buf, sizeof(buf), str,
                                               strlen("Newsgroups: "));
-                       fprintf(fp, "Newsgroups: %s\n", buf);
+                       if (!is_in_custom_headers(compose, "Newsgroups")) {
+                               fprintf(fp, "Newsgroups: %s\n", buf);
+                       }
                }
        }
 
                }
        }
 
@@ -1939,7 +1964,9 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
                                        (compose->to_list, str);
                                compose_convert_header(buf, sizeof(buf), str,
                                                       strlen("Cc: "));
                                        (compose->to_list, str);
                                compose_convert_header(buf, sizeof(buf), str,
                                                       strlen("Cc: "));
-                               fprintf(fp, "Cc: %s\n", buf);
+                               if (!is_in_custom_headers(compose, "Cc")) {
+                                       fprintf(fp, "Cc: %s\n", buf);
+                               }
                        }
                }
        }
                        }
                }
        }
@@ -1957,110 +1984,151 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
                                        compose_convert_header
                                                (buf, sizeof(buf), str,
                                                 strlen("Bcc: "));
                                        compose_convert_header
                                                (buf, sizeof(buf), str,
                                                 strlen("Bcc: "));
-                                       fprintf(fp, "Bcc: %s\n", buf);
+                                       if (!is_in_custom_headers(compose,
+                                                                 "Bcc")) {
+                                               fprintf(fp, "Bcc: %s\n", buf);
+                                       }
                                }
                        }
                }
        }
 
        /* Subject */
                                }
                        }
                }
        }
 
        /* Subject */
-       str = gtk_entry_get_text(GTK_ENTRY(compose->subject_entry));
-       if (*str != '\0') {
-               Xstrdup_a(str, str, return -1);
-               g_strstrip(str);
+       if (!is_in_custom_headers(compose, "Subject")) {
+               str = gtk_entry_get_text(GTK_ENTRY(compose->subject_entry));
                if (*str != '\0') {
                if (*str != '\0') {
-                       compose_convert_header(buf, sizeof(buf), str,
-                                              strlen("Subject: "));
-                       fprintf(fp, "Subject: %s\n", buf);
+                       Xstrdup_a(str, str, return -1);
+                       g_strstrip(str);
+                       if (*str != '\0') {
+                               compose_convert_header(buf, sizeof(buf), str,
+                                                      strlen("Subject: "));
+                               fprintf(fp, "Subject: %s\n", buf);
+                       }
                }
        }
 
        /* Message-ID */
                }
        }
 
        /* Message-ID */
-       if (compose->account->gen_msgid) {
-               compose_generate_msgid(compose, buf, sizeof(buf));
-               fprintf(fp, "Message-Id: <%s>\n", buf);
-               compose->msgid = g_strdup(buf);
+       if (!is_in_custom_headers(compose, "Message-Id")) {
+               if (compose->account->gen_msgid) {
+                       compose_generate_msgid(compose, buf, sizeof(buf));
+                       fprintf(fp, "Message-Id: <%s>\n", buf);
+                       compose->msgid = g_strdup(buf);
+               }
        }
 
        /* In-Reply-To */
        }
 
        /* In-Reply-To */
-       if (compose->inreplyto && compose->to_list)
-               fprintf(fp, "In-Reply-To: <%s>\n", compose->inreplyto);
+       if (!is_in_custom_headers(compose, "In-Reply-To")) {
+               if (compose->inreplyto && compose->to_list)
+                       fprintf(fp, "In-Reply-To: <%s>\n", compose->inreplyto);
+       }
 
        /* References */
 
        /* References */
-       if (compose->references)
-               fprintf(fp, "References: %s\n", compose->references);
+       if (!is_in_custom_headers(compose, "References")) {
+               if (compose->references)
+                       fprintf(fp, "References: %s\n", compose->references);
+       }
 
        /* Followup-To */
 
        /* Followup-To */
-       if (compose->use_followupto) {
-               str = gtk_entry_get_text(GTK_ENTRY(compose->followup_entry));
-               if (*str != '\0') {
-                       Xstrdup_a(str, str, return -1);
-                       g_strstrip(str);
-                       remove_space(str);
+       if (!is_in_custom_headers(compose, "Followup-To")) {
+               if (compose->use_followupto) {
+                       str = gtk_entry_get_text(GTK_ENTRY(compose->followup_entry));
                        if (*str != '\0') {
                        if (*str != '\0') {
-                               compose_convert_header(buf, sizeof(buf), str,
-                                                      strlen("Followup-To: "));
-                               fprintf(fp, "Followup-To: %s\n", buf);
+                               Xstrdup_a(str, str, return -1);
+                               g_strstrip(str);
+                               remove_space(str);
+                               if (*str != '\0') {
+                                       compose_convert_header(buf, sizeof(buf), str,
+                                                              strlen("Followup-To: "));
+                                       fprintf(fp, "Followup-To: %s\n", buf);
+                               }
                        }
                }
        }
 
        /* Reply-To */
                        }
                }
        }
 
        /* Reply-To */
-       if (compose->use_replyto) {
-               str = gtk_entry_get_text(GTK_ENTRY(compose->reply_entry));
-               if (*str != '\0') {
-                       Xstrdup_a(str, str, return -1);
-                       g_strstrip(str);
+       if (!is_in_custom_headers(compose, "Reply-To")) {
+               if (compose->use_replyto) {
+                       str = gtk_entry_get_text(GTK_ENTRY(compose->reply_entry));
                        if (*str != '\0') {
                        if (*str != '\0') {
-                               compose_convert_header(buf, sizeof(buf), str,
-                                                      strlen("Reply-To: "));
-                               fprintf(fp, "Reply-To: %s\n", buf);
+                               Xstrdup_a(str, str, return -1);
+                               g_strstrip(str);
+                               if (*str != '\0') {
+                                       compose_convert_header(buf, sizeof(buf), str,
+                                                              strlen("Reply-To: "));
+                                       fprintf(fp, "Reply-To: %s\n", buf);
+                               }
                        }
                }
        }
 
        /* Program version and system info */
        /* uname(&utsbuf); */
                        }
                }
        }
 
        /* Program version and system info */
        /* uname(&utsbuf); */
-       str = gtk_entry_get_text(GTK_ENTRY(compose->to_entry));
-       if (*str != '\0') {
-               fprintf(fp, "X-Mailer: %s (GTK+ %d.%d.%d; %s)\n",
-                       prog_version,
-                       gtk_major_version, gtk_minor_version, gtk_micro_version,
-                       HOST_ALIAS);
+       if (!is_in_custom_headers(compose, "X-Mailer")) {
+               str = gtk_entry_get_text(GTK_ENTRY(compose->to_entry));
+               if (*str != '\0') {
+                       fprintf(fp, "X-Mailer: %s (GTK+ %d.%d.%d; %s)\n",
+                               prog_version,
+                               gtk_major_version, gtk_minor_version, gtk_micro_version,
+                               HOST_ALIAS);
                        /* utsbuf.sysname, utsbuf.release, utsbuf.machine); */
                        /* utsbuf.sysname, utsbuf.release, utsbuf.machine); */
+               }
        }
        }
-       str = gtk_entry_get_text(GTK_ENTRY(compose->newsgroups_entry));
-       if (*str != '\0') {
+
+       if (!is_in_custom_headers(compose, "X-Newsreader")) {
+               str = gtk_entry_get_text(GTK_ENTRY(compose->newsgroups_entry));
+               if (*str != '\0') {
                fprintf(fp, "X-Newsreader: %s (GTK+ %d.%d.%d; %s)\n",
                        prog_version,
                        gtk_major_version, gtk_minor_version, gtk_micro_version,
                        HOST_ALIAS);
                        /* utsbuf.sysname, utsbuf.release, utsbuf.machine); */
                fprintf(fp, "X-Newsreader: %s (GTK+ %d.%d.%d; %s)\n",
                        prog_version,
                        gtk_major_version, gtk_minor_version, gtk_micro_version,
                        HOST_ALIAS);
                        /* utsbuf.sysname, utsbuf.release, utsbuf.machine); */
+               }
        }
 
        /* Organization */
        }
 
        /* Organization */
-       if (compose->account->organization) {
-               compose_convert_header(buf, sizeof(buf),
-                                      compose->account->organization,
-                                      strlen("Organization: "));
-               fprintf(fp, "Organization: %s\n", buf);
+       if (!is_in_custom_headers(compose, "Organization")) {
+               if (compose->account->organization) {
+                       compose_convert_header(buf, sizeof(buf),
+                                              compose->account->organization,
+                                              strlen("Organization: "));
+                       fprintf(fp, "Organization: %s\n", buf);
+               }
        }
 
        /* MIME */
        }
 
        /* MIME */
-       fprintf(fp, "Mime-Version: 1.0\n");
+       if (!is_in_custom_headers(compose, "Mime-Version")) {
+               fprintf(fp, "Mime-Version: 1.0\n");
+       }
+
        if (compose->use_attach) {
                get_rfc822_date(buf, sizeof(buf));
                subst_char(buf, ' ', '_');
                subst_char(buf, ',', '_');
                compose->boundary = g_strdup_printf("Multipart_%s_%08x",
                                                    buf, (guint)compose);
        if (compose->use_attach) {
                get_rfc822_date(buf, sizeof(buf));
                subst_char(buf, ' ', '_');
                subst_char(buf, ',', '_');
                compose->boundary = g_strdup_printf("Multipart_%s_%08x",
                                                    buf, (guint)compose);
-               fprintf(fp,
-                       "Content-Type: multipart/mixed;\n"
-                       " boundary=\"%s\"\n", compose->boundary);
+               if (!is_in_custom_headers(compose, "Content-Type")) {
+                       fprintf(fp,
+                               "Content-Type: multipart/mixed;\n"
+                               " boundary=\"%s\"\n", compose->boundary);
+               }
        } else {
        } else {
-               fprintf(fp, "Content-Type: text/plain; charset=%s\n", charset);
-               fprintf(fp, "Content-Transfer-Encoding: %s\n",
-                       procmime_get_encoding_str(encoding));
+               if (!is_in_custom_headers(compose, "Content-Type")) {
+                       fprintf(fp, "Content-Type: text/plain; charset=%s\n", charset);
+               }
+               if (!is_in_custom_headers(compose,
+                                         "Content-Transfer-Encoding")) {
+                       fprintf(fp, "Content-Transfer-Encoding: %s\n",
+                               procmime_get_encoding_str(encoding));
+               }
+       }
+
+       /* Custom Headers */
+       if (compose->account->add_customhdr) {
+               for (cur = compose->account->customhdr_list; cur != NULL;
+                    cur = cur->next) {
+                       CustomHeader * ch = (CustomHeader *) cur->data;
+                       fprintf(fp, "%s: %s\n", ch->name, ch->value);
+               }
        }
 
        /* separator between header and body */
        }
 
        /* separator between header and body */
index 498a8625202e0ea78bfdfb2be6823ffaba0e8fa9..25634786f8bc977a7205c36a7e32300a6f5d6e67 100644 (file)
@@ -46,6 +46,7 @@
 #define COMMON_RC              "sylpheedrc"
 #define ACCOUNT_RC             "accountrc"
 #define FILTER_RC              "filterrc"
 #define COMMON_RC              "sylpheedrc"
 #define ACCOUNT_RC             "accountrc"
 #define FILTER_RC              "filterrc"
+#define HEADERS_RC             "headersrc"
 #define MENU_RC                        "menurc"
 #define ADDRESS_BOOK           "addressbook.xml"
 #define MANUAL_HTML_INDEX      "sylpheed.html"
 #define MENU_RC                        "menurc"
 #define ADDRESS_BOOK           "addressbook.xml"
 #define MANUAL_HTML_INDEX      "sylpheed.html"
diff --git a/src/headers.c b/src/headers.c
new file mode 100644 (file)
index 0000000..398ec29
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999,2000 Hiroyuki Yamamoto
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include <glib.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+
+#include "intl.h"
+#include "headers.h"
+#include "utils.h"
+
+
+gchar * custom_header_get_str(CustomHeader *ch)
+{
+       return g_strdup_printf
+               ("%s\t%s: %s", ch->account_name, ch->name, ch->value);
+}
+CustomHeader * custom_header_read_str(gchar * buf)
+{
+       CustomHeader * ch;
+       gchar * account_name;
+       gchar * name;
+       gchar * value;
+       gchar * tmp;
+       Xalloca(tmp, strlen(buf) + 1, return NULL);
+       strcpy(tmp, buf);
+
+       account_name = tmp;
+
+       name = strchr(account_name, '\t');
+       if (!name)
+               return NULL;
+       else
+               *name++ = '\0';
+
+       while (*name == ' ')
+               name ++;
+       
+       ch = g_new0(CustomHeader, 1);
+
+       ch->account_name = *account_name ? g_strdup(account_name) : NULL;
+
+       value = strchr(name, ':');
+       if (!value)
+               {
+                       g_free(ch->account_name);
+                       g_free(ch);
+                       return NULL;
+               }
+       else
+               *value++ = '\0';
+       ch->name = *name ? g_strdup(name) : NULL;
+       while (*value == ' ')
+               value ++;
+
+       ch->value = *value ? g_strdup(value) : NULL;
+
+       return ch;
+}
+void custom_header_free(CustomHeader *ch)
+{
+       if (!ch) return;
+       if (ch->account_name)
+               g_free(ch->account_name);
+       if (ch->name)
+               g_free(ch->name);
+       if (ch->value)
+               g_free(ch->value);
+       g_free(ch);
+}
diff --git a/src/headers.h b/src/headers.h
new file mode 100644 (file)
index 0000000..5e6a392
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999,2000 Hiroyuki Yamamoto
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __HEADERS_H__
+#define __HEADERS_H__
+
+struct _CustomHeader
+{
+       gchar *account_name;
+       gchar *name;
+       gchar *value;
+};
+
+typedef struct _CustomHeader CustomHeader;
+
+gchar * custom_header_get_str(CustomHeader *ch);
+CustomHeader * custom_header_read_str(gchar * buf);
+void custom_header_free(CustomHeader *ch);
+
+#endif /* __FILTER_H__ */
index 886503a67f04b52e32fa12396fd34a5777838ad4..c336dc99cbaa6c56245cc1736882773e0fe74b4a 100644 (file)
@@ -297,6 +297,8 @@ static void prefs_account_ok                        (void);
 static gint prefs_account_apply                        (void);
 static void prefs_account_cancel               (void);
 
 static gint prefs_account_apply                        (void);
 static void prefs_account_cancel               (void);
 
+static void prefs_account_customhdr_edit       (void);
+
 #define VSPACING               12
 #define VSPACING_NARROW                4
 #define BOX_BORDER             16
 #define VSPACING               12
 #define VSPACING_NARROW                4
 #define BOX_BORDER             16
@@ -317,6 +319,8 @@ void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label)
        id = atoi(p);
        if (id < 0) g_warning("wrong account id: %d\n", id);
        ac_prefs->account_id = id;
        id = atoi(p);
        if (id < 0) g_warning("wrong account id: %d\n", id);
        ac_prefs->account_id = id;
+
+       prefs_headers_read_config(ac_prefs);
 }
 
 void prefs_account_save_config(PrefsAccount *ac_prefs)
 }
 
 void prefs_account_save_config(PrefsAccount *ac_prefs)
@@ -819,7 +823,7 @@ static void prefs_account_send_create(void)
        gtk_widget_show (hbox);
        gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
 
        gtk_widget_show (hbox);
        gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0);
 
-       gtk_widget_set_sensitive(hbox, FALSE);
+       //      gtk_widget_set_sensitive(hbox, FALSE);
 
        PACK_CHECK_BUTTON (hbox, customhdr_chkbtn,
                           _("Add user-defined header"));
 
        PACK_CHECK_BUTTON (hbox, customhdr_chkbtn,
                           _("Add user-defined header"));
@@ -892,6 +896,10 @@ static void prefs_account_send_create(void)
                _("Authenticate with POP3 before sending"));
        gtk_widget_set_sensitive(pop_bfr_smtp_chkbtn, FALSE);
 
                _("Authenticate with POP3 before sending"));
        gtk_widget_set_sensitive(pop_bfr_smtp_chkbtn, FALSE);
 
+       gtk_signal_connect(GTK_OBJECT(customhdr_edit_btn), "clicked",
+                          GTK_SIGNAL_FUNC(prefs_account_customhdr_edit),
+                          NULL);
+
        send.date_chkbtn      = date_chkbtn;
        send.msgid_chkbtn     = msgid_chkbtn;
        send.customhdr_chkbtn = customhdr_chkbtn;
        send.date_chkbtn      = date_chkbtn;
        send.msgid_chkbtn     = msgid_chkbtn;
        send.customhdr_chkbtn = customhdr_chkbtn;
@@ -1142,6 +1150,11 @@ static void prefs_account_cancel(void)
        gtk_main_quit();
 }
 
        gtk_main_quit();
 }
 
+static void prefs_account_customhdr_edit(void)
+{
+       prefs_headers_open(&tmp_ac_prefs);
+}
+
 #if USE_GPGME
 
 static void prefs_account_sign_key_set_data_from_radiobtn(PrefParam *pparam)
 #if USE_GPGME
 
 static void prefs_account_sign_key_set_data_from_radiobtn(PrefParam *pparam)
index 0881c7c36eaed52e0ebcf14f3d580d1287f5570a..57f40ef8307fd5b2d0a184af55505f7644b588d8 100644 (file)
@@ -84,6 +84,8 @@ struct _PrefsAccount
        gboolean use_smtp_auth;
        gboolean pop_before_smtp;
 
        gboolean use_smtp_auth;
        gboolean pop_before_smtp;
 
+       GSList *customhdr_list;
+
        /* Compose */
        gchar *sig_path;
 
        /* Compose */
        gchar *sig_path;
 
diff --git a/src/prefs_headers.c b/src/prefs_headers.c
new file mode 100644 (file)
index 0000000..90e2272
--- /dev/null
@@ -0,0 +1,945 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2001 Hiroyuki Yamamoto
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "defs.h"
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "intl.h"
+#include "main.h"
+#include "prefs.h"
+#include "prefs_headers.h"
+#include "prefs_common.h"
+#include "prefs_account.h"
+#include "mainwindow.h"
+#include "foldersel.h"
+#include "manage_window.h"
+#include "headers.h"
+#include "utils.h"
+#include "gtkutils.h"
+#include "alertpanel.h"
+#include "folder.h"
+
+static struct Headers {
+       GtkWidget *window;
+
+       GtkWidget *close_btn;
+
+       GtkWidget *hdr_combo;
+       GtkWidget *hdr_entry;
+       GtkWidget *key_entry;
+       GtkWidget *headers_clist;
+
+       /*
+       GtkWidget *hdr_combo1;
+       GtkWidget *hdr_combo2;
+       GtkWidget *hdr_entry1;
+       GtkWidget *hdr_entry2;
+       GtkWidget *key_entry1;
+       GtkWidget *key_entry2;
+       GtkWidget *pred_combo1;
+       GtkWidget *pred_combo2;
+       GtkWidget *pred_entry1;
+       GtkWidget *pred_entry2;
+       GtkWidget *op_combo;
+       GtkWidget *op_entry;
+
+       GtkWidget *dest_entry;
+       GtkWidget *regex_chkbtn;
+
+       GtkWidget *destsel_btn;
+       GtkWidget *dest_radiobtn;
+       GtkWidget *notrecv_radiobtn;
+
+       GtkWidget *cond_clist;
+       */
+} headers;
+
+/*
+   parameter name, default value, pointer to the prefs variable, data type,
+   pointer to the widget pointer,
+   pointer to the function for data setting,
+   pointer to the function for widget setting
+ */
+
+#define VSPACING               12
+#define VSPACING_NARROW                4
+#define DEFAULT_ENTRY_WIDTH    80
+#define PREFSBUFSIZE           1024
+
+/* widget creating functions */
+static void prefs_headers_create               (void);
+
+static void prefs_headers_set_dialog   (PrefsAccount * ac);
+static void prefs_headers_set_list     (PrefsAccount * ac);
+static gint prefs_headers_clist_set_row        (PrefsAccount * ac,
+                                        gint    row);
+
+/* callback functions */
+static void prefs_headers_select_dest_cb       (void);
+static void prefs_headers_register_cb  (void);
+static void prefs_headers_substitute_cb        (void);
+static void prefs_headers_delete_cb    (void);
+static void prefs_headers_up           (void);
+static void prefs_headers_down         (void);
+static void prefs_headers_select               (GtkCList       *clist,
+                                        gint            row,
+                                        gint            column,
+                                        GdkEvent       *event);
+
+static void prefs_headers_dest_radio_button_toggled    (void);
+static void prefs_headers_notrecv_radio_button_toggled (void);
+
+static void prefs_headers_key_pressed  (GtkWidget      *widget,
+                                        GdkEventKey    *event,
+                                        gpointer        data);
+static void prefs_headers_close                (GtkButton      *button);
+
+static PrefsAccount * cur_ac = NULL;
+
+void prefs_headers_open(PrefsAccount * ac)
+{
+       if (!headers.window) {
+               prefs_headers_create();
+       }
+
+       manage_window_set_transient(GTK_WINDOW(headers.window));
+       gtk_widget_grab_focus(headers.close_btn);
+
+       prefs_headers_set_dialog(ac);
+
+       cur_ac = ac;
+
+       gtk_widget_show(headers.window);
+}
+
+static void prefs_headers_create(void)
+{
+       GtkWidget *window;
+       GtkWidget *vbox;
+       GtkWidget *close_btn;
+       GtkWidget *confirm_area;
+
+       GtkWidget *vbox1;
+
+       GtkWidget *table1;
+       GtkWidget *hdr_label;
+       GtkWidget *hdr_combo;
+       GtkWidget *key_label;
+       GtkWidget *key_entry;
+
+       GtkWidget *reg_hbox;
+       GtkWidget *btn_hbox;
+       GtkWidget *arrow;
+       GtkWidget *reg_btn;
+       GtkWidget *subst_btn;
+       GtkWidget *del_btn;
+
+       GtkWidget *ch_hbox;
+       GtkWidget *ch_scrolledwin;
+       GtkWidget *headers_clist;
+
+       GtkWidget *btn_vbox;
+       GtkWidget *up_btn;
+       GtkWidget *down_btn;
+       /*
+
+       GtkWidget *table1;
+       GtkWidget *op_label;
+       GtkWidget *op_combo;
+       GtkWidget *op_entry;
+       GtkWidget *hdr_label;
+       GtkWidget *hdr_combo1;
+       GtkWidget *hdr_combo2;
+       GtkWidget *key_label;
+       GtkWidget *key_entry1;
+       GtkWidget *key_entry2;
+       GtkWidget *pred_label;
+       GtkWidget *pred_combo1;
+       GtkWidget *pred_entry1;
+       GtkWidget *pred_combo2;
+       GtkWidget *pred_entry2;
+
+       GtkWidget *vbox2;
+       GtkWidget *dest_hbox;
+       GtkWidget *dest_entry;
+       GtkWidget *destsel_btn;
+       GtkWidget *dest_radiobtn;
+       GtkWidget *notrecv_radiobtn;
+       GSList *recv_group = NULL;
+
+       GtkWidget *regex_chkbtn;
+
+       GtkWidget *reg_hbox;
+       GtkWidget *btn_hbox;
+       GtkWidget *arrow;
+       GtkWidget *reg_btn;
+       GtkWidget *subst_btn;
+       GtkWidget *del_btn;
+
+       GtkWidget *cond_hbox;
+       GtkWidget *cond_scrolledwin;
+       GtkWidget *cond_clist;
+
+       GtkWidget *btn_vbox;
+       GtkWidget *up_btn;
+       GtkWidget *down_btn;
+       */
+
+       gchar *title[] = {_("Custom headers")};
+
+       debug_print(_("Creating headers setting window...\n"));
+
+       window = gtk_window_new (GTK_WINDOW_DIALOG);
+       gtk_container_set_border_width (GTK_CONTAINER (window), 8);
+       gtk_window_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
+       gtk_window_set_modal (GTK_WINDOW (window), TRUE);
+       gtk_window_set_policy (GTK_WINDOW (window), FALSE, TRUE, FALSE);
+
+       vbox = gtk_vbox_new (FALSE, 6);
+       gtk_widget_show (vbox);
+       gtk_container_add (GTK_CONTAINER (window), vbox);
+
+       gtkut_button_set_create (&confirm_area, &close_btn, _("Close"),
+                                NULL, NULL, NULL, NULL);
+       gtk_widget_show (confirm_area);
+       gtk_box_pack_end (GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
+       gtk_widget_grab_default (close_btn);
+
+       gtk_window_set_title (GTK_WINDOW(window),
+                             _("Headers setting"));
+       gtk_signal_connect (GTK_OBJECT(window), "delete_event",
+                           GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete), NULL);
+       gtk_signal_connect (GTK_OBJECT(window), "key_press_event",
+                           GTK_SIGNAL_FUNC(prefs_headers_key_pressed), NULL);
+       gtk_signal_connect (GTK_OBJECT(window), "focus_in_event",
+                           GTK_SIGNAL_FUNC(manage_window_focus_in), NULL);
+       gtk_signal_connect (GTK_OBJECT(window), "focus_out_event",
+                           GTK_SIGNAL_FUNC(manage_window_focus_out), NULL);
+       gtk_signal_connect (GTK_OBJECT(close_btn), "clicked",
+                           GTK_SIGNAL_FUNC(prefs_headers_close), NULL);
+
+       vbox1 = gtk_vbox_new (FALSE, VSPACING);
+       gtk_widget_show (vbox1);
+       gtk_box_pack_start (GTK_BOX (vbox), vbox1, TRUE, TRUE, 0);
+       gtk_container_set_border_width (GTK_CONTAINER (vbox1), 2);
+
+       table1 = gtk_table_new (2, 2, FALSE);
+       gtk_widget_show (table1);
+       gtk_box_pack_start (GTK_BOX (vbox1), table1,
+                           FALSE, FALSE, 0);
+       gtk_table_set_row_spacings (GTK_TABLE (table1), 8);
+       gtk_table_set_col_spacings (GTK_TABLE (table1), 8);
+
+       /*
+       op_label = gtk_label_new (_("Operator"));
+       gtk_widget_show (op_label);
+       gtk_table_attach (GTK_TABLE (table1), op_label, 0, 1, 0, 1,
+                         GTK_FILL, 0, 0, 0);
+       gtk_misc_set_alignment (GTK_MISC (op_label), 0, 0.5);
+
+       op_combo = gtk_combo_new ();
+       gtk_widget_show (op_combo);
+       gtk_table_attach (GTK_TABLE (table1), op_combo, 0, 1, 2, 3,
+                         0, 0, 0, 0);
+       gtk_widget_set_usize (op_combo, 52, -1);
+       gtkut_combo_set_items (GTK_COMBO (op_combo), "and", "or", NULL);
+
+       op_entry = GTK_COMBO (op_combo)->entry;
+       gtk_entry_set_editable (GTK_ENTRY (op_entry), FALSE);
+
+       hdr_label = gtk_label_new (_("Header"));
+       gtk_widget_show (hdr_label);
+       gtk_table_attach (GTK_TABLE (table1), hdr_label, 1, 2, 0, 1,
+                         GTK_FILL, 0, 0, 0);
+       gtk_misc_set_alignment (GTK_MISC (hdr_label), 0, 0.5);
+
+       hdr_combo1 = gtk_combo_new ();
+       gtk_widget_show (hdr_combo1);
+       gtk_table_attach (GTK_TABLE (table1), hdr_combo1, 1, 2, 1, 2,
+                         0, 0, 0, 0);
+       gtk_widget_set_usize (hdr_combo1, 96, -1);
+       gtkut_combo_set_items (GTK_COMBO (hdr_combo1),
+                              "Subject", "From", "To", "Cc", "Reply-To",
+                              "Sender", "X-ML-Name", "X-List", "X-Sequence",
+                              "X-Mailer",
+                              NULL);
+
+       hdr_combo2 = gtk_combo_new ();
+       gtk_widget_show (hdr_combo2);
+       gtk_table_attach (GTK_TABLE (table1), hdr_combo2, 1, 2, 2, 3,
+                         0, 0, 0, 0);
+       gtk_widget_set_usize (hdr_combo2, 96, -1);
+       gtkut_combo_set_items (GTK_COMBO (hdr_combo2), _("(none)"),
+                              "Subject", "From", "To", "Cc", "Reply-To",
+                              "Sender", "X-ML-Name", "X-List", "X-Sequence",
+                              "X-Mailer",
+                              NULL);
+
+       key_label = gtk_label_new (_("Keyword"));
+       gtk_widget_show (key_label);
+       gtk_table_attach (GTK_TABLE (table1), key_label, 2, 3, 0, 1,
+                         GTK_EXPAND | GTK_SHRINK | GTK_FILL,
+                         0, 0, 0);
+       gtk_misc_set_alignment (GTK_MISC (key_label), 0, 0.5);
+
+       key_entry1 = gtk_entry_new ();
+       gtk_widget_show (key_entry1);
+       gtk_widget_set_usize (key_entry1, 128, -1);
+       gtk_table_attach (GTK_TABLE (table1), key_entry1, 2, 3, 1, 2,
+                         GTK_EXPAND | GTK_SHRINK | GTK_FILL,
+                         0, 0, 0);
+
+       key_entry2 = gtk_entry_new ();
+       gtk_widget_show (key_entry2);
+       gtk_widget_set_usize (key_entry2, 128, -1);
+       gtk_table_attach (GTK_TABLE (table1), key_entry2, 2, 3, 2, 3,
+                         GTK_EXPAND | GTK_SHRINK | GTK_FILL,
+                         0, 0, 0);
+
+       pred_label = gtk_label_new (_("Predicate"));
+       gtk_widget_show (pred_label);
+       gtk_table_attach (GTK_TABLE (table1), pred_label, 3, 4, 0, 1,
+                         GTK_FILL, 0, 0, 0);
+       gtk_misc_set_alignment (GTK_MISC (pred_label), 0, 0.5);
+
+       pred_combo1 = gtk_combo_new ();
+       gtk_widget_show (pred_combo1);
+       gtk_table_attach (GTK_TABLE (table1), pred_combo1, 3, 4, 1, 2,
+                         0, 0, 0, 0);
+       gtk_widget_set_usize (pred_combo1, 92, -1);
+       gtkut_combo_set_items (GTK_COMBO (pred_combo1),
+                              _("contains"), _("not contain"), NULL);
+
+       pred_entry1 = GTK_COMBO (pred_combo1)->entry;
+       gtk_entry_set_editable (GTK_ENTRY (pred_entry1), FALSE);
+
+       pred_combo2 = gtk_combo_new ();
+       gtk_widget_show (pred_combo2);
+       gtk_table_attach (GTK_TABLE (table1), pred_combo2, 3, 4, 2, 3,
+                         0, 0, 0, 0);
+       gtk_widget_set_usize (pred_combo2, 92, -1);
+       gtkut_combo_set_items (GTK_COMBO (pred_combo2),
+                              _("contains"), _("not contain"), NULL);
+
+       pred_entry2 = GTK_COMBO (pred_combo2)->entry;
+       gtk_entry_set_editable (GTK_ENTRY (pred_entry2), FALSE);
+       */
+
+       /* destination */
+
+       /*
+       vbox2 = gtk_vbox_new (FALSE, VSPACING_NARROW);
+       gtk_widget_show (vbox2);
+       gtk_box_pack_start (GTK_BOX (vbox1), vbox2, FALSE, TRUE, 0);
+
+       dest_hbox = gtk_hbox_new (FALSE, 8);
+       gtk_widget_show (dest_hbox);
+       gtk_box_pack_start (GTK_BOX (vbox2), dest_hbox, FALSE, TRUE, 0);
+
+       dest_radiobtn =
+               gtk_radio_button_new_with_label (recv_group, _("Destination"));
+       recv_group = gtk_radio_button_group (GTK_RADIO_BUTTON (dest_radiobtn));
+       gtk_widget_show (dest_radiobtn);
+       gtk_box_pack_start (GTK_BOX (dest_hbox), dest_radiobtn,
+                           FALSE, FALSE, 0);
+       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dest_radiobtn), TRUE);
+       gtk_signal_connect
+               (GTK_OBJECT (dest_radiobtn), "toggled",
+                GTK_SIGNAL_FUNC (prefs_headers_dest_radio_button_toggled),
+                NULL);
+
+       dest_entry = gtk_entry_new ();
+       gtk_widget_show (dest_entry);
+       gtk_widget_set_usize (dest_entry, DEFAULT_ENTRY_WIDTH, -1);
+       gtk_box_pack_start (GTK_BOX (dest_hbox), dest_entry, TRUE, TRUE, 0);
+       gtk_entry_set_editable (GTK_ENTRY (dest_entry), FALSE);
+
+       destsel_btn = gtk_button_new_with_label (_(" Select... "));
+       gtk_widget_show (destsel_btn);
+       gtk_box_pack_start (GTK_BOX (dest_hbox), destsel_btn, FALSE, FALSE, 0);
+       gtk_signal_connect (GTK_OBJECT (destsel_btn), "clicked",
+                           GTK_SIGNAL_FUNC (prefs_headers_select_dest_cb),
+                           NULL);
+
+       PACK_CHECK_BUTTON (dest_hbox, regex_chkbtn, _("Use regex"));
+       gtk_widget_set_sensitive(regex_chkbtn, FALSE);
+
+       notrecv_radiobtn = gtk_radio_button_new_with_label
+               (recv_group, _("Don't receive"));
+       recv_group = gtk_radio_button_group
+               (GTK_RADIO_BUTTON (notrecv_radiobtn));
+       gtk_widget_show (notrecv_radiobtn);
+       gtk_box_pack_start (GTK_BOX (vbox2), notrecv_radiobtn, FALSE, FALSE, 0);
+       gtk_signal_connect
+               (GTK_OBJECT (notrecv_radiobtn), "toggled",
+                GTK_SIGNAL_FUNC (prefs_headers_notrecv_radio_button_toggled),
+                NULL);
+       */
+
+       /* register / substitute / delete */
+
+       /*
+       reg_hbox = gtk_hbox_new (FALSE, 4);
+       gtk_widget_show (reg_hbox);
+       gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox, FALSE, FALSE, 0);
+
+       arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
+       gtk_widget_show (arrow);
+       gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0);
+       gtk_widget_set_usize (arrow, -1, 16);
+
+       btn_hbox = gtk_hbox_new (TRUE, 4);
+       gtk_widget_show (btn_hbox);
+       gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0);
+
+       reg_btn = gtk_button_new_with_label (_("Register"));
+       gtk_widget_show (reg_btn);
+       gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0);
+       gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
+                           GTK_SIGNAL_FUNC (prefs_headers_register_cb), NULL);
+
+       subst_btn = gtk_button_new_with_label (_(" Substitute "));
+       gtk_widget_show (subst_btn);
+       gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0);
+       gtk_signal_connect (GTK_OBJECT (subst_btn), "clicked",
+                           GTK_SIGNAL_FUNC (prefs_headers_substitute_cb),
+                           NULL);
+
+       del_btn = gtk_button_new_with_label (_("Delete"));
+       gtk_widget_show (del_btn);
+       gtk_box_pack_start (GTK_BOX (btn_hbox), del_btn, FALSE, TRUE, 0);
+       gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
+                           GTK_SIGNAL_FUNC (prefs_headers_delete_cb), NULL);
+
+       cond_hbox = gtk_hbox_new (FALSE, 8);
+       gtk_widget_show (cond_hbox);
+       gtk_box_pack_start (GTK_BOX (vbox1), cond_hbox, TRUE, TRUE, 0);
+
+       cond_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
+       gtk_widget_show (cond_scrolledwin);
+       gtk_widget_set_usize (cond_scrolledwin, -1, 150);
+       gtk_box_pack_start (GTK_BOX (cond_hbox), cond_scrolledwin,
+                           TRUE, TRUE, 0);
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (cond_scrolledwin),
+                                       GTK_POLICY_AUTOMATIC,
+                                       GTK_POLICY_AUTOMATIC);
+
+       cond_clist = gtk_clist_new_with_titles(1, title);
+       gtk_widget_show (cond_clist);
+       gtk_container_add (GTK_CONTAINER (cond_scrolledwin), cond_clist);
+       gtk_clist_set_column_width (GTK_CLIST (cond_clist), 0, 80);
+       gtk_clist_set_selection_mode (GTK_CLIST (cond_clist),
+                                     GTK_SELECTION_BROWSE);
+       GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (cond_clist)->column[0].button,
+                               GTK_CAN_FOCUS);
+       gtk_signal_connect (GTK_OBJECT (cond_clist), "select_row",
+                           GTK_SIGNAL_FUNC (prefs_headers_select), NULL);
+
+       btn_vbox = gtk_vbox_new (FALSE, 8);
+       gtk_widget_show (btn_vbox);
+       gtk_box_pack_start (GTK_BOX (cond_hbox), btn_vbox, FALSE, FALSE, 0);
+
+       up_btn = gtk_button_new_with_label (_("Up"));
+       gtk_widget_show (up_btn);
+       gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
+       gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
+                           GTK_SIGNAL_FUNC (prefs_headers_up), NULL);
+
+       down_btn = gtk_button_new_with_label (_("Down"));
+       gtk_widget_show (down_btn);
+       gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
+       gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
+                           GTK_SIGNAL_FUNC (prefs_headers_down), NULL);
+       */
+
+       hdr_label = gtk_label_new (_("Header"));
+       gtk_widget_show (hdr_label);
+       gtk_table_attach (GTK_TABLE (table1), hdr_label, 0, 1, 0, 1,
+                         GTK_EXPAND | GTK_SHRINK | GTK_FILL,
+                         0, 0, 0);
+       gtk_misc_set_alignment (GTK_MISC (hdr_label), 0, 0.5);
+       
+       hdr_combo = gtk_combo_new ();
+       gtk_widget_show (hdr_combo);
+       gtk_table_attach (GTK_TABLE (table1), hdr_combo, 0, 1, 1, 2,
+                         GTK_EXPAND | GTK_SHRINK | GTK_FILL,
+                         0, 0, 0);
+       gtk_widget_set_usize (hdr_combo, 150 /* 96 */, -1);
+       gtkut_combo_set_items (GTK_COMBO (hdr_combo),
+                              "User-Agent", "X-Operating-System", NULL);
+
+       key_label = gtk_label_new (_("Value"));
+       gtk_widget_show (key_label);
+       gtk_table_attach (GTK_TABLE (table1), key_label, 1, 2, 0, 1,
+                         GTK_EXPAND | GTK_SHRINK | GTK_FILL,
+                         0, 0, 0);
+       gtk_misc_set_alignment (GTK_MISC (key_label), 0, 0.5);
+       
+       key_entry = gtk_entry_new ();
+       gtk_widget_show (key_entry);
+       gtk_table_attach (GTK_TABLE (table1), key_entry, 1, 2, 1, 2,
+                         GTK_EXPAND | GTK_SHRINK | GTK_FILL,
+                         0, 0, 0);
+
+       /* register / substitute / delete */
+
+       reg_hbox = gtk_hbox_new (FALSE, 4);
+       gtk_widget_show (reg_hbox);
+       gtk_box_pack_start (GTK_BOX (vbox1), reg_hbox,
+                           FALSE, FALSE, 0);
+
+       arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_OUT);
+       gtk_widget_show (arrow);
+       gtk_box_pack_start (GTK_BOX (reg_hbox), arrow, FALSE, FALSE, 0);
+       gtk_widget_set_usize (arrow, -1, 16);
+
+       btn_hbox = gtk_hbox_new (TRUE, 4);
+       gtk_widget_show (btn_hbox);
+       gtk_box_pack_start (GTK_BOX (reg_hbox), btn_hbox, FALSE, FALSE, 0);
+
+       reg_btn = gtk_button_new_with_label (_("Add"));
+       gtk_widget_show (reg_btn);
+       gtk_box_pack_start (GTK_BOX (btn_hbox), reg_btn, FALSE, TRUE, 0);
+       gtk_signal_connect (GTK_OBJECT (reg_btn), "clicked",
+                           GTK_SIGNAL_FUNC (prefs_headers_register_cb), NULL);
+
+       subst_btn = gtk_button_new_with_label (_(" Substitute "));
+       gtk_widget_show (subst_btn);
+       gtk_box_pack_start (GTK_BOX (btn_hbox), subst_btn, FALSE, TRUE, 0);
+       gtk_signal_connect (GTK_OBJECT (subst_btn), "clicked",
+                           GTK_SIGNAL_FUNC (prefs_headers_substitute_cb),
+                           NULL);
+
+       del_btn = gtk_button_new_with_label (_("Delete"));
+       gtk_widget_show (del_btn);
+       gtk_box_pack_start (GTK_BOX (btn_hbox), del_btn, FALSE, TRUE, 0);
+       gtk_signal_connect (GTK_OBJECT (del_btn), "clicked",
+                           GTK_SIGNAL_FUNC (prefs_headers_delete_cb), NULL);
+
+
+       ch_hbox = gtk_hbox_new (FALSE, 8);
+       gtk_widget_show (ch_hbox);
+       gtk_box_pack_start (GTK_BOX (vbox1), ch_hbox,
+                           TRUE, TRUE, 0);
+
+       ch_scrolledwin = gtk_scrolled_window_new (NULL, NULL);
+       gtk_widget_set_usize (ch_scrolledwin, -1, 100);
+       gtk_widget_show (ch_scrolledwin);
+       gtk_box_pack_start (GTK_BOX (ch_hbox), ch_scrolledwin,
+                           TRUE, TRUE, 0);
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (ch_scrolledwin),
+                                       GTK_POLICY_AUTOMATIC,
+                                       GTK_POLICY_AUTOMATIC);
+
+       headers_clist = gtk_clist_new_with_titles(1, title);
+       gtk_widget_show (headers_clist);
+       gtk_container_add (GTK_CONTAINER (ch_scrolledwin), headers_clist);
+       gtk_clist_set_column_width (GTK_CLIST (headers_clist), 0, 80);
+       gtk_clist_set_selection_mode (GTK_CLIST (headers_clist),
+                                     GTK_SELECTION_BROWSE);
+       GTK_WIDGET_UNSET_FLAGS (GTK_CLIST (headers_clist)->column[0].button,
+                               GTK_CAN_FOCUS);
+       gtk_signal_connect (GTK_OBJECT (headers_clist), "select_row",
+                           GTK_SIGNAL_FUNC (prefs_headers_select),
+                           NULL);
+
+
+       btn_vbox = gtk_vbox_new (FALSE, 8);
+       gtk_widget_show (btn_vbox);
+       gtk_box_pack_start (GTK_BOX (ch_hbox), btn_vbox, FALSE, FALSE, 0);
+
+       up_btn = gtk_button_new_with_label (_("Up"));
+       gtk_widget_show (up_btn);
+       gtk_box_pack_start (GTK_BOX (btn_vbox), up_btn, FALSE, FALSE, 0);
+       gtk_signal_connect (GTK_OBJECT (up_btn), "clicked",
+                           GTK_SIGNAL_FUNC (prefs_headers_up), NULL);
+
+       down_btn = gtk_button_new_with_label (_("Down"));
+       gtk_widget_show (down_btn);
+       gtk_box_pack_start (GTK_BOX (btn_vbox), down_btn, FALSE, FALSE, 0);
+       gtk_signal_connect (GTK_OBJECT (down_btn), "clicked",
+                           GTK_SIGNAL_FUNC (prefs_headers_down), NULL);
+
+
+       gtk_widget_show_all(window);
+
+       headers.window    = window;
+       headers.close_btn = close_btn;
+
+       headers.hdr_combo  = hdr_combo;
+       headers.hdr_entry  = GTK_COMBO (hdr_combo)->entry;
+       headers.key_entry  = key_entry;
+       headers.headers_clist   = headers_clist;
+
+       /*
+       headers.hdr_combo1  = hdr_combo1;
+       headers.hdr_combo2  = hdr_combo2;
+       headers.hdr_entry1  = GTK_COMBO (hdr_combo1)->entry;
+       headers.hdr_entry2  = GTK_COMBO (hdr_combo2)->entry;
+       headers.key_entry1  = key_entry1;
+       headers.key_entry2  = key_entry2;
+       headers.pred_combo1 = pred_combo1;
+       headers.pred_combo2 = pred_combo2;
+       headers.pred_entry1 = pred_entry1;
+       headers.pred_entry2 = pred_entry2;
+       headers.op_combo    = op_combo;
+       headers.op_entry    = op_entry;
+
+       headers.dest_entry      = dest_entry;
+       headers.destsel_btn     = destsel_btn;
+       headers.dest_radiobtn   = dest_radiobtn;
+       headers.notrecv_radiobtn        = notrecv_radiobtn;
+       headers.regex_chkbtn     = regex_chkbtn;
+
+       headers.headers_clist   = headers_clist;
+       */
+}
+
+void prefs_headers_read_config(PrefsAccount * ac)
+{
+       gchar *rcpath;
+       FILE *fp;
+       gchar buf[PREFSBUFSIZE];
+       CustomHeader *ch;
+
+       debug_print(_("Reading headers configuration...\n"));
+
+       rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, HEADERS_RC, NULL);
+       if ((fp = fopen(rcpath, "r")) == NULL) {
+               if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
+               g_free(rcpath);
+               ac->customhdr_list = NULL;
+               return;
+       }
+       g_free(rcpath);
+
+       /* remove all previous headers list */
+       while (ac->customhdr_list != NULL) {
+               ch = (CustomHeader *)ac->customhdr_list->data;
+               custom_header_free(ch);
+               ac->customhdr_list = g_slist_remove(ac->customhdr_list, ch);
+       }
+       while (fgets(buf, sizeof(buf), fp) != NULL) {
+               g_strchomp(buf);
+               ch = custom_header_read_str(buf);
+               if (ch) {
+                       if (strcmp(ch->account_name, ac->account_name) == 0)
+                               ac->customhdr_list =
+                                       g_slist_append(ac->customhdr_list, ch);
+                       else
+                               custom_header_free(ch);
+               }
+       }
+       fclose(fp);
+}
+
+void prefs_headers_write_config(PrefsAccount * ac)
+{
+       gchar *rcpath;
+       PrefFile *pfile;
+       GSList *cur;
+       gchar buf[PREFSBUFSIZE];
+       FILE * fp;
+       CustomHeader *ch;
+
+       GSList *all_hdrs = NULL;
+
+       debug_print(_("Writing headers configuration...\n"));
+
+       rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, HEADERS_RC, NULL);
+
+       if ((fp = fopen(rcpath, "r")) == NULL) {
+               if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
+       }
+       else {
+               all_hdrs = NULL;
+
+               while (fgets(buf, sizeof(buf), fp) != NULL) {
+                       g_strchomp(buf);
+                       ch = custom_header_read_str(buf);
+                       if (ch) {
+                               if (strcmp(ch->account_name, ac->account_name) != 0)
+                                       all_hdrs =
+                                               g_slist_append(all_hdrs, ch);
+                               else
+                                       custom_header_free(ch);
+                       }
+               }
+
+               fclose(fp);
+       }
+
+       if ((pfile = prefs_write_open(rcpath)) == NULL) {
+               g_warning(_("failed to write configuration to file\n"));
+               g_free(rcpath);
+               return;
+       }
+
+       for (cur = all_hdrs; cur != NULL; cur = cur->next) {
+               CustomHeader *hdr = (CustomHeader *)cur->data;
+               gchar *chstr;
+
+               chstr = custom_header_get_str(hdr);
+               if (fputs(chstr, pfile->fp) == EOF ||
+                   fputc('\n', pfile->fp) == EOF) {
+                       FILE_OP_ERROR(rcpath, "fputs || fputc");
+                       prefs_write_close_revert(pfile);
+                       g_free(rcpath);
+                       g_free(chstr);
+                       return;
+               }
+               g_free(chstr);
+       }
+
+       for (cur = ac->customhdr_list; cur != NULL; cur = cur->next) {
+               CustomHeader *hdr = (CustomHeader *)cur->data;
+               gchar *chstr;
+
+               chstr = custom_header_get_str(hdr);
+               if (fputs(chstr, pfile->fp) == EOF ||
+                   fputc('\n', pfile->fp) == EOF) {
+                       FILE_OP_ERROR(rcpath, "fputs || fputc");
+                       prefs_write_close_revert(pfile);
+                       g_free(rcpath);
+                       g_free(chstr);
+                       return;
+               }
+               g_free(chstr);
+       }
+
+       g_free(rcpath);
+
+       while (all_hdrs != NULL) {
+               ch = (CustomHeader *)all_hdrs->data;
+               custom_header_free(ch);
+               all_hdrs = g_slist_remove(all_hdrs, ch);
+       }
+
+       if (prefs_write_close(pfile) < 0) {
+               g_warning(_("failed to write configuration to file\n"));
+               return;
+       }
+}
+
+static void prefs_headers_set_dialog(PrefsAccount * ac)
+{
+       GtkCList *clist = GTK_CLIST(headers.headers_clist);
+       GSList *cur;
+       gchar *ch_str[1];
+       gint row;
+
+       gtk_clist_freeze(clist);
+       gtk_clist_clear(clist);
+
+       ch_str[0] = _("(New)");
+       row = gtk_clist_append(clist, ch_str);
+       gtk_clist_set_row_data(clist, row, NULL);
+
+       for (cur = ac->customhdr_list; cur != NULL; cur = cur->next) {
+               CustomHeader *ch = (CustomHeader *)cur->data;
+
+               ch_str[0] = g_strdup_printf("%s: %s", ch->name, ch->value);
+               row = gtk_clist_append(clist, ch_str);
+               gtk_clist_set_row_data(clist, row, ch);
+
+               g_free(ch_str[0]);
+       }
+
+       gtk_clist_thaw(clist);
+}
+
+static void prefs_headers_set_list(PrefsAccount * ac)
+{
+       gint row = 1;
+       CustomHeader *ch;
+
+       g_slist_free(ac->customhdr_list);
+       ac->customhdr_list = NULL;
+
+       while ((ch = gtk_clist_get_row_data(GTK_CLIST(headers.headers_clist),
+               row)) != NULL) {
+               ac->customhdr_list = g_slist_append(ac->customhdr_list,
+                                                     ch);
+               row++;
+       }
+}
+
+#define GET_ENTRY(entry) \
+       entry_text = gtk_entry_get_text(GTK_ENTRY(entry))
+
+static gint prefs_headers_clist_set_row(PrefsAccount * ac, gint row)
+{
+       GtkCList *clist = GTK_CLIST(headers.headers_clist);
+       CustomHeader *ch;
+       gchar *entry_text;
+       gchar *ch_str[1];
+
+       g_return_val_if_fail(row != 0, -1);
+
+       GET_ENTRY(headers.hdr_entry);
+       if (entry_text[0] == '\0') {
+               alertpanel_error(_("Header name is not set."));
+               return -1;
+       }
+
+       ch = g_new0(CustomHeader, 1);
+
+       ch->account_name = g_strdup(ac->account_name);
+
+       ch->name = g_strdup(entry_text);
+
+       GET_ENTRY(headers.key_entry);
+       if (entry_text[0] != '\0')
+               ch->value = g_strdup(entry_text);
+
+       ch_str[0] = g_strdup_printf("%s: %s", ch->name, ch->value);
+
+       if (row < 0)
+               row = gtk_clist_append(clist, ch_str);
+       else {
+               CustomHeader *tmpch;
+
+               gtk_clist_set_text(clist, row, 0, ch_str[0]);
+               tmpch = gtk_clist_get_row_data(clist, row);
+               if (tmpch)
+                       custom_header_free(tmpch);
+       }
+
+       gtk_clist_set_row_data(clist, row, ch);
+
+       g_free(ch_str[0]);
+
+       prefs_headers_set_list(cur_ac);
+
+       return row;
+}
+
+static void prefs_headers_register_cb(void)
+{
+       prefs_headers_clist_set_row(cur_ac, -1);
+}
+
+static void prefs_headers_substitute_cb(void)
+{
+       GtkCList *clist = GTK_CLIST(headers.headers_clist);
+       CustomHeader *ch;
+       gint row;
+
+       if (!clist->selection) return;
+
+       row = GPOINTER_TO_INT(clist->selection->data);
+       if (row == 0) return;
+
+       ch = gtk_clist_get_row_data(clist, row);
+       if (!ch) return;
+
+       prefs_headers_clist_set_row(cur_ac, row);
+}
+
+static void prefs_headers_delete_cb(void)
+{
+       GtkCList *clist = GTK_CLIST(headers.headers_clist);
+       CustomHeader *ch;
+       gint row;
+
+       if (!clist->selection) return;
+       row = GPOINTER_TO_INT(clist->selection->data);
+       if (row == 0) return;
+
+       if (alertpanel(_("Delete header"),
+                      _("Do you really want to delete this header?"),
+                      _("Yes"), _("No"), NULL) == G_ALERTALTERNATE)
+               return;
+
+       ch = gtk_clist_get_row_data(clist, row);
+       custom_header_free(ch);
+       gtk_clist_remove(clist, row);
+       cur_ac->customhdr_list = g_slist_remove(cur_ac->customhdr_list, ch);
+}
+
+static void prefs_headers_up(void)
+{
+       GtkCList *clist = GTK_CLIST(headers.headers_clist);
+       gint row;
+
+       if (!clist->selection) return;
+
+       row = GPOINTER_TO_INT(clist->selection->data);
+       if (row > 1) {
+               gtk_clist_row_move(clist, row, row - 1);
+               prefs_headers_set_list(cur_ac);
+       }
+}
+
+static void prefs_headers_down(void)
+{
+       GtkCList *clist = GTK_CLIST(headers.headers_clist);
+       gint row;
+
+       if (!clist->selection) return;
+
+       row = GPOINTER_TO_INT(clist->selection->data);
+       if (row > 0 && row < clist->rows - 1) {
+               gtk_clist_row_move(clist, row, row + 1);
+               prefs_headers_set_list(cur_ac);
+       }
+}
+
+#define ENTRY_SET_TEXT(entry, str) \
+       gtk_entry_set_text(GTK_ENTRY(entry), str ? str : "")
+
+static void prefs_headers_select(GtkCList *clist, gint row, gint column,
+                               GdkEvent *event)
+{
+       CustomHeader *ch;
+       CustomHeader default_ch = { "", NULL };
+       ch = gtk_clist_get_row_data(clist, row);
+       if (!ch)
+               ch = &default_ch;
+       ENTRY_SET_TEXT(headers.hdr_entry, ch->name);
+       ENTRY_SET_TEXT(headers.key_entry, ch->value);
+}
+
+static void prefs_headers_key_pressed(GtkWidget *widget, GdkEventKey *event,
+                                    gpointer data)
+{
+       if (event && event->keyval == GDK_Escape)
+               gtk_widget_hide(headers.window);
+}
+
+static void prefs_headers_close(GtkButton *button)
+{
+       prefs_headers_write_config(cur_ac);
+       gtk_widget_hide(headers.window);
+}
diff --git a/src/prefs_headers.h b/src/prefs_headers.h
new file mode 100644 (file)
index 0000000..89a82c3
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2001 Hiroyuki Yamamoto
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PREFS_HEADERS_H__
+#define __PREFS_HEADERS_H__
+
+void prefs_headers_read_config (PrefsAccount * ac);
+void prefs_headers_write_config        (PrefsAccount * ac);
+void prefs_headers_open         (PrefsAccount * ac);
+
+#endif /* __PREFS_HEADERS_H__ */