You need to test your patch more rigorously before attaching here. Some parts of it does not work. 

All custom headers takes some values which I have not set. 

We also need to have a NONE support for custom headers.

I have some more review comments anyway and these need to be incorporated next time.

Configure.in is diffed against some older version and contains a lot of unnecessary changes. 
All that needs to go away.


--- /dev/null	2007-09-22 03:20:58.000000000 +0530
> > +++ plugins/email-custom-header/Makefile.am	2007-12-17 12:13:27.000000000 +0530
> @@ -0,0 +1,62 @@
> +INCLUDES = -I. 						\
> +	-I$(top_srcdir)	                                \
> +	-I$(top_srcdir)/widgets				\
> +	-I$(top_srcdir)/widgets/misc			\
> +	-I$(top_builddir)/mail                          \
> +	-I$(top_srcdir)/camel                           \
> +	-I$(top_builddir)/composer			\
> +	$(EVOLUTION_MAIL_CFLAGS)			\
> +	-DEVOLUTION_GLADEDIR=\""$(gladedir)"\"          \
> +	-DCONNECTOR_GLADEDIR=\""$(gladedir)"\"
> +
> +
> +@EVO_PLUGIN_RULE@
> +
> +plugin_DATA =	\
> +	org-gnome-custom-header.eplug	\
> +	org-gnome-custom-header-menu.xml  
> +
> +plugin_LTLIBRARIES = liborg-gnome-custom-header.la
> +
> +liborg_gnome_custom_header_la_SOURCES = 		\
> +	email-custom-header.c					\
> +	custom-header.c					\
> +	email-custom-header.h					
> +liborg_gnome_custom_header_la_LIBADD = 			\
> +	$(top_builddir)/e-util/libeutil.la 			\
> +	$(top_builddir)/widgets/misc/libemiscwidgets.la		\
> +	$(top_builddir)/mail/libevolution-mail.la 		\
> +	$(NO_UNDEFINED_REQUIRED_LIBS)				
> +
> +liborg_gnome_custom_header_la_LDFLAGS = -module -avoid-version $(NO_UNDEFINED)
> +
> +schemadir       = $(GCONF_SCHEMA_FILE_DIR)
> +schema_in_files = apps_evolution_email_custom_header.schemas.in
> +schema_DATA     = $(schema_in_files:.schemas.in=.schemas)
> +
> +@INTLTOOL_SCHEMAS_RULE@
> +
> +install-data-local:
> +	if test -z "$(DESTDIR)" ; then											\
> +		for p in $(schema_DATA) ; do										\
> +			GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $$p;	\
> +		done													\
> +	fi
> +
> +errordir = $(privdatadir)/errors
> +
> +glade_DATA =							\
> +	org-gnome-custom-header.glade
> +
> +EXTRA_DIST = 							\
> +	org-gnome-custom-header.eplug.xml			\
> +	org-gnome-custom-header-menu.xml			\	
> +	$(schema_in_files)					\
> +	$(error_DATA)						
> +
> +BUILT_SOURCES = 				\
> +	org-gnome-custom-header.eplug 			\
> +	$(error_i18n)
> +
> +CLEANFILES = $(BUILT_SOURCES)
> +DISTCLEANFILES = $(schema_DATA)
> --- /dev/null	2007-09-22 03:20:58.000000000 +0530
> +++ plugins/email-custom-header/apps_evolution_email_custom_header.schemas.in	2007-12-13 17:27:21.000000000 +0530
> @@ -0,0 +1,17 @@
> +<gconfschemafile>
> +  <schemalist>
> +    <schema>
> +      <key>/schemas/apps/evolution/mail/composer/customheaders</key>
> +      <applyto>/apps/evolution/mail/composer/customheaders</applyto>
> +      <owner>evolution-mail</owner>
> +      <type>list</type>
> +      <list_type>string</list_type>
> +      <default>[Security=Personal;Unclassified;Protected;InConfidence;Secret;Topsecret]</default>

This isn't getting installed. 

> +      <locale name="C">
> +         <short>List of subtype</short>
> +         <long>List of subtype</long>
> +      </locale>
> +    </schema>
> +  </schemalist>
> +</gconfschemafile>
> +
> --- /dev/null	2007-09-22 03:20:58.000000000 +0530
> +++ plugins/email-custom-header/org-gnome-custom-header.eplug.xml	2007-12-17 12:40:08.000000000 +0530
> @@ -0,0 +1,22 @@
> +<?xml version="1.0"?>
> +<e-plugin-list>
> +	<e-plugin id="org.gnome.evolution.email-custom-header" type="shlib" _name="Custom Header" 
> +		location="@PLUGINDIR@/liborg-gnome-custom-header@SOEXT@">
> +
> +		<author name="Ashish Shrivastava" email="shashish@novell.com"/>
> +		<_description>A plugin to help you attach Custom Headers to the outgoing messages. You can configure the custom header through the Custom Header dialog box.</_description>

This must change. It needs to be more descriptive.

> +
> +		<hook class="org.gnome.evolution.mail.bonobomenu:1.0">
> +			<menu id="org.gnome.evolution.mail.composer" target="widget">
> +				<ui file="@PLUGINDIR@/org-gnome-custom-header-menu.xml"/>
> +				<item
> +					type="item"
> +					verb="Custom Header"
> +					path="/commands/Custom Header"			   
> +					activate="org_gnome_composer_custom_header"
> +					enable="one"
> +				/>
> +			</menu>
> +		</hook>
> +	</e-plugin>
> +</e-plugin-list>
> --- /dev/null	2007-09-22 03:20:58.000000000 +0530
> +++ plugins/email-custom-header/email-custom-header.c	2007-12-17 16:37:58.000000000 +0530
> @@ -0,0 +1,436 @@
> +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
> + *
> + * Authors: Ashish Shrivastava <shashish@novell.com>
> + *
> + * Copyright (C) 2004 Novell, Inc.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of version 2 of the GNU General Public
> + * License as published by the Free Software Foundation.
> + *
> + * 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., 51 Franklin Street, Fifth Floor, MA 02110-1301.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <string.h>
> +#include <glib.h>
> +#include <gtk/gtk.h>

As I mentioned last time, this is bad. Include individual files.

> +
> +#include <gconf/gconf-client.h>
> +
> +#include <libedataserverui/e-name-selector.h>
> +#include <libedataserverui/e-contact-store.h>
> +#include <e-util/e-error.h>
> +#include <libgnome/libgnome.h>
> +#include <libgnome/gnome-i18n.h>
> +#include <glade/glade.h>
> +#include <libxml/tree.h>
> +#include <libxml/parser.h>
> +#include <libxml/xmlmemory.h>
> +#include <e-util/e-xml-utils.h>
> +#include "composer/e-msg-composer.h"
> +#include "composer/e-msg-composer-hdrs.h"
> +#include "libedataserver/e-account.h"
> +#include "e-util/e-util-private.h"
> +
> +#include "email-custom-header.h"
> +
> +struct _CustomHeaderOptionsDialogPrivate {
> +	/* Glade XML data */
> +	GladeXML *xml;
> +
> +	/*Widgets*/
> +
> +	GtkWidget *main;
> +
> +	GtkWidget *page;
> +
> +	GtkNotebook *notebook;
> +
> +	GtkWidget *header_table;
> +
> +	GtkWidget *header_type_name_label;
> +
> +	GtkWidget *header_subtype_value_combo_box[MAX_ROW][MAX_COLUMN];
> +	char *help_section;
> +};
> +
> +
> +static void epech_custom_headeroptions_dialog_class_init (GObjectClass *object_class);
> +static void epech_custom_headeroptions_dialog_finalize (GObject *object);
> +static void epech_custom_headeroptions_dialog_init (GObject *object);
> +static void epech_custom_headeroptions_dialog_dispose (GObject *object);
> +static void epech_setup_custom_header_widgets (CustomHeaderOptionsDialog *mch);
> +
> +static GObjectClass *parent_class = NULL;
> +enum {
> +	MCH_RESPONSE,
> +	LAST_SIGNAL
> +};
> +
> +GArray *index_subtype_header;
> +
> +static guint signals[LAST_SIGNAL] = {0};
> +
> +CustomHeaderDetails headerDetails[MAX_ROW];
> +
> +/* custom_header_options_get_widgets_data(CustomHeaderOptionsDialog *mch)
> +   Return Value:This function returns a -1 if an error occurs. In case of error-free operation 
> +   a 1 is returned.
> + */
> +
> +static gint
> +epech_custom_header_options_get_widgets_data (CustomHeaderOptionsDialog *mch)
> +{
> +	CustomHeaderOptionsDialogPrivate *priv;
> +	gint index_combobox_row,index_combobox_column;
> +	priv = mch->priv;
> +
> +	index_subtype_header = g_array_new (TRUE, FALSE, sizeof (gint));
> +
> +	/* This block helps us fetch the address of the delegator(s). If no delegator is 
> +	   selected or more than one delegatee has been selected then an info dialog is 
> +	   popped up to help the user.	
> +	 */

???

> +
> +	for(index_combobox_row=0,index_combobox_column=0; 
> +			index_combobox_column<headerDetails[0].numberOfHeader;index_combobox_column++) {
> +		gint result;
> +
> +		result = gtk_combo_box_get_active(
> +				(GtkComboBox *)priv->header_subtype_value_combo_box
> +				[index_combobox_row][index_combobox_column]);

There is some bug here I guess. I don't see the values I set. Why do you want to use a complex 2-d array ?

> +		g_array_append_val (index_subtype_header, result);
> +	}
> +
> +	return 1;
> +}
> +
> +static gboolean
> +epech_get_widgets (CustomHeaderOptionsDialog *mch) 
> +{
> +	CustomHeaderOptionsDialogPrivate *priv;
> +
> +	priv = mch->priv;
> +
> +#define CUSTOM_HEADER(name) glade_xml_get_widget (priv->xml, name)
> +
> +	priv->main = CUSTOM_HEADER ("custom_header");
> +	if (!priv->main)
> +		return FALSE;
> +
> +	priv->page  = CUSTOM_HEADER ("vbox");	
> +	priv->notebook = (GtkNotebook *) CUSTOM_HEADER ("notebook");
> +	priv->header_table = CUSTOM_HEADER ("header-options");	

Perhaps they should be named better.

> +
> +#undef CUSTOM_HEADER
> +
> +	return (priv->page
> +			&&priv->notebook
> +			&&priv->header_table);
> +}
> +
> +static void
> +epech_custom_header_options_fill_widgets_with_data (CustomHeaderOptionsDialog *mch)
> +{
> +	CustomHeaderOptionsDialogPrivate *priv;
> +	gint set_index_combobox_row,set_index_combobox_column;	
> +	priv = mch->priv;
> +
> +	priv->help_section = g_strdup ("usage-mail");
> +
> +	for(set_index_combobox_row=0,set_index_combobox_column=0; 
> +			set_index_combobox_column<headerDetails[0].numberOfHeader; 
> +			set_index_combobox_column++) {
> +
> +		gtk_combo_box_set_active (
> +				(GtkComboBox *)priv->header_subtype_value_combo_box
> +				[set_index_combobox_row][set_index_combobox_column],0);
> +
> +	}
> +}
> +
> +CustomHeaderOptionsDialog *
> +epech_custom_headeroptions_dialog_new (void) {
> +	CustomHeaderOptionsDialog *mch;
> +
> +	mch = g_object_new (CUSTOM_HEADER_OPTIONS_DIALOG, NULL);
> +
> +	return mch;
> +}
> +
> +GType epech_custom_headeroptions_dialog_get_type (void)
> +{
> +	static GType type = 0;
> +	if (type == 0) {
> +		static const GTypeInfo info = {
> +			sizeof (CustomHeaderOptionsDialogClass),
> +			NULL,   /* base_init */
> +			NULL,   /* base_finalize */
> +			(GClassInitFunc) epech_custom_headeroptions_dialog_class_init,   /* class_init */
> +			NULL,   /* class_finalize */
> +			NULL,   /* class_data */
> +			sizeof (CustomHeaderOptionsDialog),
> +			0,      /* n_preallocs */
> +			(GInstanceInitFunc) epech_custom_headeroptions_dialog_init,
> +			NULL    /* instance_init */
> +		};
> +		type = g_type_register_static (G_TYPE_OBJECT,
> +				"CustomHeaderOptionsDialogType",
> +				&info, 0);
> +	}
> +	return type;
> +}
> +
> +static void epech_custom_header_options_cb (GtkDialog *dialog, gint state, gpointer func_data)
> +{
> +	CustomHeaderOptionsDialogPrivate *priv;
> +	CustomHeaderOptionsDialog *mch;
> +	GError *error = NULL;     
> +
> +	mch = func_data;
> +	priv = mch->priv;
> +
> +	switch (state) {			
> +		case GTK_RESPONSE_OK:
> +			if(epech_custom_header_options_get_widgets_data (mch) < 0) 
> +				return;
> +		case GTK_RESPONSE_CANCEL:
> +			gtk_widget_hide (priv->main);
> +			gtk_widget_destroy (priv->main);
> +			g_object_unref (priv->xml);
> +			break;	     
> +		case GTK_RESPONSE_HELP:
> +			gnome_help_display (
> +					"evolution.xml", priv->help_section, &error);
> +			if (error != NULL) {
> +				g_warning ("%s", error->message);
> +				g_error_free (error);
> +			}
> +			break;
> +	}
> +	g_signal_emit (G_OBJECT (func_data), signals[MCH_RESPONSE], 0, state);
> +
> +}
> +
> +gboolean 
> +epech_custom_headeroptions_dialog_run (CustomHeaderOptionsDialog *mch, GtkWidget *parent)
> +{	
> +	CustomHeaderOptionsDialogPrivate *priv;
> +
> +	GtkWidget *toplevel;
> +	gchar *filename;
> +
> +	g_return_val_if_fail (mch != NULL || CUSTOM_IS_HEADEROPTIONS_DIALOG (mch), FALSE);
> +
> +	priv = mch->priv;
> +
> +	epech_get_custom_header_type_list ();
> +
> +	filename = g_build_filename (EVOLUTION_GLADEDIR,
> +			"org-gnome-custom-header.glade",

This file name should be org-gnome-email-custom-header.glade 
Look at other plugins.


Everytime we click on the option, the glade file is re-read. Should split up init and populate. Ideally all these should be in the dialog_new code and the dialog object should be reused.


Another important thing is: If I set something in custom-headers options and fi I relaunch the dialog, the options that I have set last time should be retained.

> +			NULL);
> +	priv->xml = glade_xml_new (filename, NULL, NULL);
> +	g_free (filename);
> +
> +	if (!priv->xml) {
> +		g_message ( G_STRLOC ": Could not load the Glade XML file ");
> +		return FALSE;

These return values should be handled and appropriate error messages should be popped up. 

> +	}
> +
> +	if (!epech_get_widgets(mch)) {
> +		g_object_unref (priv->xml);
> +		g_message (G_STRLOC ": Could not get the Widgets \n");
> +		return FALSE;
> +	}
> +
> +	epech_setup_custom_header_widgets (mch);
> +
> +	toplevel =  gtk_widget_get_toplevel (priv->main);
> +	if (parent)
> +		gtk_window_set_transient_for (GTK_WINDOW (toplevel),
> +				GTK_WINDOW (parent));
> +
> +	epech_custom_header_options_fill_widgets_with_data (mch);
> +
> +	g_signal_connect (GTK_DIALOG (priv->main), "response", 
> +			G_CALLBACK(epech_custom_header_options_cb), mch);
> +
> +	gtk_window_set_modal ((GtkWindow *) priv->main, TRUE);
> +	gtk_widget_show (priv->main);
> +
> +	return TRUE;
> +}
> +
> +void epech_get_custom_header_type_list (void)
> +{
> +
> +	GConfClient *gconf;
> +	gconf = gconf_client_get_default (); 
> +
> +	epech_custom_header_list_new_for_gconf (gconf, "/apps/evolution/mail/composer/email_custom_header/customheader");

This should ideally be in /apps/evolution/plugins/email-custom-header

> +
> +	return;
> +}
> +
> +void epech_custom_header_list_new_for_gconf (GConfClient *client,const char *path)

Is it not meaningful to make this static ? Should this even be a function on its own ?

> +{
> +	g_return_val_if_fail (GCONF_IS_CLIENT (client), NULL);
> +	g_return_val_iffail (path != NULL, NULL);

This should be in the calling part. 

> +
> +	gconf_client_add_dir (client, path,GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
> +
> +	epech_load_from_gconf_custom_header (client, path);
> +
> +	return;
> +}
> +
> +
> +void epech_load_from_gconf_custom_header (GConfClient *client,const char *path)
> +{
> +	GSList *header_list,*q;
> +	gchar *buffer;
> +	gint index,num_elements,pos;
> +
> +	memset(headerDetails, 0, sizeof(headerDetails));

Ugly. Use GSList of synamic objects.

> +	header_list = gconf_client_get_list (client,path,GCONF_VALUE_STRING, NULL);
> +
> +	gint headerTypeIndex=0;
> +
> +	for (q = header_list,pos = 0;q != NULL;q = q->next,pos++) {
> +		buffer = q->data;
> +
> +		gchar **parse_header_list = g_strsplit_set (buffer, "=;,", -1);
> +
> +		strcpy(headerDetails[headerTypeIndex].type, parse_header_list[0]);
> +
> +		for (index = 0;parse_header_list[index+1];++index) { 
> +			strcpy(headerDetails[headerTypeIndex].subTypeHeader[index].subtype,parse_header_list[index+1]);
> +		}

Leaks. Leaks.

Always prefer to use g_* functions.


> +
> +		headerDetails[headerTypeIndex].numberOfSubTypeHeader = index;
> +		headerTypeIndex++;
> +
> +	}
> +	headerDetails[0].numberOfHeader = pos;

This is unacceptable.

> +}
> +
> +static void 
> +epech_setup_custom_header_widgets (CustomHeaderOptionsDialog *mch)
> +{
> +	CustomHeaderOptionsDialogPrivate *priv;
> +	gint header_section_id,sub_type_index,row,column,label_row;
> +	priv = mch->priv;
> +
> +	for (header_section_id=0,label_row=0,row=0,column=1; 
> +			header_section_id<headerDetails[0].numberOfHeader;header_section_id++,row++,column++) {

Bad spacing. 

Also, where is the headerDetails initialized ? Will this even work ? 

What is this numberOfHeader ? It is badly named as well as badly designed. It looks like a hack to check the number of items.

You definitely cannot declare a hard-coded 50-element array. Memory is precious. 
This has to change to a List based thingy.

> +
> +		priv->header_type_name_label = gtk_label_new ("");
> +		gtk_label_set_markup (GTK_LABEL (priv->header_type_name_label), 
> +				headerDetails[header_section_id].type);
> +		gtk_table_attach (GTK_TABLE (priv->header_table), priv->header_type_name_label, 0, 1, row, column,
> +				(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
> +				(GtkAttachOptions) (0), 0, 0);
> +		gtk_misc_set_alignment (GTK_MISC (priv->header_type_name_label), 0, 0.5);
> +		gtk_widget_show (priv->header_type_name_label);
> +
> +		priv->header_subtype_value_combo_box[label_row][row] = gtk_combo_box_new_text ();
> +		gtk_table_attach (GTK_TABLE (priv->header_table), 
> +				priv->header_subtype_value_combo_box[label_row][row], 1, 2, row, column,
> +				(GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
> +				(GtkAttachOptions) (GTK_FILL), 0, 0);
> +
> +		for (sub_type_index=0;sub_type_index<headerDetails[header_section_id].numberOfSubTypeHeader;sub_type_index++) {
> +			gtk_combo_box_append_text (GTK_COMBO_BOX (priv->header_subtype_value_combo_box[label_row][row]), 
> +					headerDetails[header_section_id].subTypeHeader[sub_type_index].subtype);
> +		}
> +		gtk_widget_show (priv->header_subtype_value_combo_box[label_row][row]);
> +	}
> +}
> +
> +static void
> +epech_custom_headeroptions_dialog_class_init (GObjectClass *object)
> +{
> +	CustomHeaderOptionsDialogClass *klass;
> +	GObjectClass *object_class;
> +
> +	klass = CUSTOM_HEADEROPTIONS_DIALOG_CLASS (object);
> +	parent_class = g_type_class_peek_parent (klass);
> +	object_class = G_OBJECT_CLASS (klass);
> +
> +	object_class->finalize = epech_custom_headeroptions_dialog_finalize;
> +	object_class->dispose = epech_custom_headeroptions_dialog_dispose;
> +
> +	signals[MCH_RESPONSE] = g_signal_new ("emch_response",
> +			G_TYPE_FROM_CLASS (klass),
> +			G_SIGNAL_RUN_FIRST,
> +			G_STRUCT_OFFSET (CustomHeaderOptionsDialogClass, emch_response),
> +			NULL, NULL,
> +			g_cclosure_marshal_VOID__INT,
> +			G_TYPE_NONE, 1,
> +			G_TYPE_INT);
> +
> +}
> +
> +static void
> +epech_custom_headeroptions_dialog_init (GObject *object)
> +{
> +
> +	CustomHeaderOptionsDialog *mch;
> +	CustomHeaderOptionsDialogPrivate *priv;
> +
> +	mch = CUSTOM_HEADEROPTIONS_DIALOG (object);
> +
> +	priv = g_new0 (CustomHeaderOptionsDialogPrivate, 1);
> +
> +	mch->priv = priv;
> +
> +	priv->xml = NULL;
> +	priv->main = NULL;
> +	priv->notebook = NULL;
> +	priv->header_table = NULL;
> +}
> +
> +static void
> +epech_custom_headeroptions_dialog_finalize (GObject *object)
> +{
> +	CustomHeaderOptionsDialog *mch = (CustomHeaderOptionsDialog *)object;
> +	CustomHeaderOptionsDialogPrivate *priv;
> +
> +	g_return_if_fail (CUSTOM_IS_HEADEROPTIONS_DIALOG (mch));
> +	priv = mch->priv;
> +
> +	g_free (priv->help_section);
> +
> +	if (mch->priv) {
> +		g_free (mch->priv);
> +		mch->priv = NULL;
> +	}
> +
> +	if (parent_class->finalize) 
> +		(* parent_class->finalize) (object);
> +
> +}
> +
> +static void
> +epech_custom_headeroptions_dialog_dispose (GObject *object)
> +{
> +	CustomHeaderOptionsDialog *mch = (CustomHeaderOptionsDialog *) object;
> +
> +	g_return_if_fail (CUSTOM_IS_HEADEROPTIONS_DIALOG (mch));
> +
> +	if (parent_class->dispose)
> +		(* parent_class->dispose) (object);
> +
> +}	
> +
> --- /dev/null	2007-09-22 03:20:58.000000000 +0530
> +++ plugins/email-custom-header/custom-header.c	2007-12-17 16:36:33.000000000 +0530
> @@ -0,0 +1,111 @@
> +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
> + *
> + *  Authors: Ashish Shrivastava <shashish@novell.com>
> + *
> + * Copyright 2004 Novell, Inc. (www.novell.com)
> + * 
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of version 2 of the GNU General Public
> + * License as published by the Free Software Foundation.
> + * 
> + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> + *
> + */
> +
> +#include <string.h>
> +#include <stdio.h>
> +
> +#include <glib.h>
> +#include <glib/gi18n.h>
> +
> +#include <camel/camel-mime-message.h>
> +#include <camel/camel-address.h>
> +#include <gtk/gtk.h>

Not good for compilation.

> +#include <glib/gi18n.h>
> +#include <mail/em-menu.h>
> +#include <e-util/e-error.h>
> +#include <e-util/e-xml-utils.h>
> +
> +#include <string.h>
> +#include <sys/stat.h>
> +#include <e-util/e-config.h>
> +
> +#include <e-util/e-config.h>
> +#include <mail/em-config.h>
> +#include <mail/em-event.h>
> +
> +#include "composer/e-msg-composer.h"
> +#include "composer/e-msg-composer-hdrs.h"
> +#include "libedataserver/e-account.h"
> +
> +#include "email-custom-header.h"
> +
> +#define d(x) x
> +
> +extern GArray *index_subtype_header;
> +extern CustomHeaderDetails headerDetails[MAX_ROW];

No. We really need a GArray or a GSList or such. No hard-coded values.

> +
> +void org_gnome_composer_custom_header (EPlugin * ep, EMMenuTargetWidget * target);
> +
> +static CustomHeaderOptionsDialog *dialog=NULL;
> +
> +
> +static void  
> +epech_append_to_custom_header (CustomHeaderOptionsDialog *dialog, gint state, gpointer data)
> +{
> +	EMsgComposer *composer;
> +	gint index, index_subtype;
> +
> +	composer = (EMsgComposer *)data;
> +	if (state == GTK_RESPONSE_OK) {
> +
> +		for(index=0,index_subtype=0;index_subtype<headerDetails[index].numberOfHeader;index_subtype++)

Coding style has gone for a toss. As I mentioned last time, proper spacing needs to be given.


> +		{
> +			e_msg_composer_modify_header (composer, headerDetails[index_subtype].type,
> +					headerDetails[index].subTypeHeader[g_array_index(index_subtype_header, gint, index_subtype)].subtype);		
> +		}			
> +	}
> +}
> +
> +
> +static void
> +epech_custom_header_options_commit (EMsgComposer *comp, gpointer user_data)
> +{
> +	if (!user_data && !CUSTOM_IS_HEADEROPTIONS_DIALOG (user_data))
> +		return;
> +
> +	if (dialog) {
> +		g_print ("\nDialog getting unreferenced ");
> +		g_object_unref (dialog);
> +		dialog = NULL;	
> +	}
> +}
> +
> +void 
> +org_gnome_composer_custom_header (EPlugin * ep, EMMenuTargetWidget * t)
> +{
> +
> +	EMsgComposer *composer;
> +
> +	composer = (EMsgComposer *) t->target.widget;
> +
> +	/*disply the custome_header options dialog*/
> +	if (!dialog) {
> +		g_print ("New dialog\n\n") ;

Debug statements should be optional.

> +		dialog = epech_custom_headeroptions_dialog_new () ;
> +	}
> +
> +	epech_custom_headeroptions_dialog_run (dialog, GTK_WIDGET (composer));

This can be defined in this same file. Why do we need two different files ?

> +
> +	g_signal_connect (dialog, "emch_response", G_CALLBACK (epech_append_to_custom_header), GTK_WIDGET (composer));
> +	g_signal_connect (GTK_WIDGET (composer), "destroy",
> +			G_CALLBACK (epech_custom_header_options_commit), dialog);
> +
> +}
> --- /dev/null	2007-09-22 03:20:58.000000000 +0530
> +++ plugins/email-custom-header/email-custom-header.h	2007-12-17 16:31:11.000000000 +0530
> @@ -0,0 +1,73 @@
> + /* Evolution Email custom header options
> + * Copyright (C) 2004 Novell, Inc.
> + *
> + * Authors: Ashish <shashish@novell.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of version 2 of the GNU General Public
> + * License as published by the Free Software Foundation.
> + *
> + * 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., 51 Franklin Street, Fifth Floor, MA 02110-1301.
> + */
> +
> +#ifndef __CUSTOM_HEADEROPTIONS_DIALOG_H__
> +#define __CUSTOM_HEADEROPTIONS_DIALOG_H__
> +
> +#include <gtk/gtkwidget.h>
> +#include <gtk/gtk.h>
> +
> +
> +
> +#define CUSTOM_HEADER_OPTIONS_DIALOG       (epech_custom_headeroptions_dialog_get_type ())
> +#define CUSTOM_HEADEROPTIONS_DIALOG(obj)       (GTK_CHECK_CAST ((obj), CUSTOM_HEADER_OPTIONS_DIALOG, CustomHeaderOptionsDialog))
> +#define CUSTOM_HEADEROPTIONS_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), CUSTOM_HEADER_OPTIONS_DIALOG, CustomHeaderOptionsDialogClass))
> +#define CUSTOM_IS_HEADEROPTIONS_DIALOG(obj)    (GTK_CHECK_TYPE ((obj), CUSTOM_HEADER_OPTIONS_DIALOG))
> +#define CUSTOM_IS_HEADEROPTIONS_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), CUSTOM_HEADER_OPTIONS_DIALOG))
> +
> +#define CUSTOM_SUB_TYPE 50
> +#define CUSTOM_TYPE 50
> +#define MAX_ROW 50
> +#define MAX_COLUMN 50

This is how *not* to implement this.

> +
> +
> +typedef struct _CustomHeaderOptionsDialog		CustomHeaderOptionsDialog;
> +typedef struct _CustomHeaderOptionsDialogClass		CustomHeaderOptionsDialogClass;
> +typedef struct _CustomHeaderOptionsDialogPrivate	CustomHeaderOptionsDialogPrivate;
> +
> +struct _CustomHeaderOptionsDialog {
> +	GObject object;
> +
> +	/* Private data */
> +	CustomHeaderOptionsDialogPrivate *priv;
> +};
> +
> +typedef struct {
> +	gchar subtype[CUSTOM_SUB_TYPE];
> +} CustomHeaderSubType;
> +
> +typedef struct {
> +	gchar type[CUSTOM_TYPE];
> +	gint numberOfHeader;
> +	gint numberOfSubTypeHeader;
> +	CustomHeaderSubType subTypeHeader[CUSTOM_SUB_TYPE];
> +} CustomHeaderDetails;
> +
> +struct _CustomHeaderOptionsDialogClass {
> +	GObjectClass parent_class;
> +	void (* emch_response) (CustomHeaderOptionsDialog *esd, gint status);
> +};
> +
> +GType  epech_custom_headeroptions_dialog_get_type     (void);
> +CustomHeaderOptionsDialog *epech_custom_headeroptions_dialog_new (void);
> +gboolean epech_custom_headeroptions_dialog_run (CustomHeaderOptionsDialog *mch, GtkWidget *parent);
> +void epech_get_custom_header_type_list (void);
> +void epech_load_from_gconf_custom_header (GConfClient *client,const char *path);
> +#endif
> +
> 
