[evolution/kill-bonobo] Seal up ESignature and add GObject properties.



commit 052e89dd423b5ba2f394f55c2fcc48102e7b9bc3
Author: Matthew Barnes <mbarnes redhat com>
Date:   Thu Aug 6 17:48:45 2009 -0400

    Seal up ESignature and add GObject properties.

 composer/e-msg-composer.c            |   28 +-
 e-util/e-signature-list.c            |   42 +-
 e-util/e-signature-utils.c           |   12 +-
 e-util/e-signature.c                 |  631 ++++++++++++++++----
 e-util/e-signature.h                 |   84 ++-
 mail/em-account-editor.c             |   26 +-
 mail/em-composer-prefs.c             | 1080 ++++++++++++++++++++++++++++++++++
 modules/mail/e-mail-shell-migrate.c  |    2 +-
 widgets/misc/e-signature-combo-box.c |    6 +-
 widgets/misc/e-signature-editor.c    |   32 +-
 widgets/misc/e-signature-manager.c   |   47 +-
 widgets/misc/e-signature-preview.c   |   13 +-
 widgets/misc/e-signature-tree-view.c |    7 +-
 13 files changed, 1762 insertions(+), 248 deletions(-)
---
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index c2d8899..55bfc84 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -1013,13 +1013,16 @@ skip_content:
 /* Signatures */
 
 static gchar *
-encode_signature_name (const gchar *name)
+encode_signature_uid (ESignature *signature)
 {
+	const gchar *uid;
 	const gchar *s;
 	gchar *ename, *e;
 	gint len = 0;
 
-	s = name;
+	uid = e_signature_get_uid (signature);
+
+	s = uid;
 	while (*s) {
 		len ++;
 		if (*s == '"' || *s == '.' || *s == '=')
@@ -1029,7 +1032,7 @@ encode_signature_name (const gchar *name)
 
 	ename = g_new (gchar, len + 1);
 
-	s = name;
+	s = uid;
 	e = ename;
 	while (*s) {
 		if (*s == '"') {
@@ -1121,18 +1124,19 @@ get_signature_html (EMsgComposer *composer)
 	if (!signature)
 		return NULL;
 
-	if (!signature->autogen) {
-		if (!signature->filename)
+	if (!e_signature_get_autogenerated (signature)) {
+		const gchar *filename;
+
+		filename = e_signature_get_filename (signature);
+		if (filename == NULL)
 			return NULL;
 
-		format_html = signature->html;
+		format_html = e_signature_get_is_html (signature);
 
-		if (signature->script)
-			text = e_run_signature_script (
-				signature->filename);
+		if (e_signature_get_is_script (signature))
+			text = e_run_signature_script (filename);
 		else
-			text = e_read_signature_file (
-				signature, TRUE, NULL);
+			text = e_read_signature_file (signature, TRUE, NULL);
 	} else {
 		EAccount *account;
 		EAccountIdentity *id;
@@ -1169,7 +1173,7 @@ get_signature_html (EMsgComposer *composer)
 		gchar *encoded_uid = NULL;
 
 		if (signature)
-			encoded_uid = encode_signature_name (signature->uid);
+			encoded_uid = encode_signature_uid (signature);
 
 		/* The signature dash convention ("-- \n") is specified in the
 		 * "Son of RFC 1036": http://www.chemie.fu-berlin.de/outerspace/netnews/son-of-1036.html,
diff --git a/e-util/e-signature-list.c b/e-util/e-signature-list.c
index 094d478..3fd4f8a 100644
--- a/e-util/e-signature-list.c
+++ b/e-util/e-signature-list.c
@@ -153,8 +153,7 @@ add_autogen (ESignatureList *list, GSList *new_sigs)
 	ESignature *autogen;
 
 	autogen = e_signature_new ();
-	autogen->name = g_strdup ("Autogenerated");
-	autogen->autogen = TRUE;
+	e_signature_set_autogenerated (autogen, TRUE);
 
 	e_list_append (E_LIST (list), autogen);
 
@@ -182,8 +181,11 @@ gconf_signatures_changed (GConfClient *client, guint cnxn_id, GConfEntry *entry,
 		if ((uid = e_signature_uid_from_xml (l->data))) {
 			/* See if this is an existing signature */
 			for (iter = e_list_get_iterator (old_sigs); e_iterator_is_valid (iter); e_iterator_next (iter)) {
+				const gchar *signature_uid;
+
 				signature = (ESignature *) e_iterator_get (iter);
-				if (!strcmp (signature->uid, uid)) {
+				signature_uid = e_signature_get_uid (signature);
+				if (!strcmp (signature_uid, uid)) {
 					/* The signature still exists, so remove
 					 * it from "old_sigs" and update it.
 					 */
@@ -192,7 +194,7 @@ gconf_signatures_changed (GConfClient *client, guint cnxn_id, GConfEntry *entry,
 					if (e_signature_set_from_xml (signature, l->data))
 						g_signal_emit (signature_list, signals[SIGNATURE_CHANGED], 0, signature);
 
-					have_autogen |= signature->autogen;
+					have_autogen |= e_signature_get_autogenerated (signature);
 
 					break;
 				}
@@ -204,11 +206,8 @@ gconf_signatures_changed (GConfClient *client, guint cnxn_id, GConfEntry *entry,
 		if (!found) {
 			/* Must be a new signature */
 			signature = e_signature_new_from_xml (l->data);
-			have_autogen |= signature->autogen;
-			if (!signature->uid) {
-				signature->uid = e_uid_new ();
-				resave = TRUE;
-			}
+			have_autogen |= e_signature_get_autogenerated (signature);
+			resave = TRUE;
 
 			e_list_append (E_LIST (signature_list), signature);
 			new_sigs = g_slist_prepend (new_sigs, signature);
@@ -422,9 +421,11 @@ e_signature_list_remove (ESignatureList *signatures, ESignature *signature)
  * Return value: The signature or NULL if it doesn't exist.
  **/
 const ESignature *
-e_signature_list_find (ESignatureList *signatures, e_signature_find_t type, const gchar *key)
+e_signature_list_find (ESignatureList *signatures,
+                       e_signature_find_t type,
+                       const gchar *key)
 {
-	const ESignature *signature = NULL;
+	ESignature *signature = NULL;
 	EIterator *it;
 
 	/* this could use a callback for more flexibility ...
@@ -436,20 +437,21 @@ e_signature_list_find (ESignatureList *signatures, e_signature_find_t type, cons
 	for (it = e_list_get_iterator ((EList *) signatures);
 	     e_iterator_is_valid (it);
 	     e_iterator_next (it)) {
-		gint found = 0;
+		const gchar *value;
 
-		signature = (const ESignature *) e_iterator_get (it);
+		/* XXX EIterator misuses const. */
+		signature = (ESignature *) e_iterator_get (it);
 
 		switch (type) {
-		case E_SIGNATURE_FIND_NAME:
-			found = strcmp (signature->name, key) == 0;
-			break;
-		case E_SIGNATURE_FIND_UID:
-			found = strcmp (signature->uid, key) == 0;
-			break;
+			case E_SIGNATURE_FIND_NAME:
+				value = e_signature_get_name (signature);
+				break;
+			case E_SIGNATURE_FIND_UID:
+				value = e_signature_get_uid (signature);
+				break;
 		}
 
-		if (found)
+		if (g_strcmp0 (value, key) == 0)
 			break;
 
 		signature = NULL;
diff --git a/e-util/e-signature-utils.c b/e-util/e-signature-utils.c
index 1321fc5..4ae5ac2 100644
--- a/e-util/e-signature-utils.c
+++ b/e-util/e-signature-utils.c
@@ -153,25 +153,29 @@ e_read_signature_file (ESignature *signature,
 	CamelStream *input_stream;
 	CamelStream *output_stream;
 	GByteArray *buffer;
+	const gchar *filename;
+	gboolean is_html;
 	gchar *content;
 	gsize length;
 	gint fd;
 
 	g_return_val_if_fail (E_IS_SIGNATURE (signature), NULL);
 
-	fd = g_open (signature->filename, O_RDONLY, 0);
+	filename = e_signature_get_filename (signature);
+	is_html = e_signature_get_is_html (signature);
+
+	fd = g_open (filename, O_RDONLY, 0);
 	if (fd < 0) {
 		g_set_error (
 			error, G_FILE_ERROR,
 			g_file_error_from_errno (errno),
-			"%s: %s", signature->filename,
-			g_strerror (errno));
+			"%s: %s", filename, g_strerror (errno));
 		return NULL;
 	}
 
 	input_stream = camel_stream_fs_new_with_fd (fd);
 
-	if (!signature->html && convert_to_html) {
+	if (!is_html && convert_to_html) {
 		CamelStreamFilter *filtered_stream;
 		CamelMimeFilter *filter;
 		gint32 flags;
diff --git a/e-util/e-signature.c b/e-util/e-signature.c
index 86e29fe..1b22dba 100644
--- a/e-util/e-signature.c
+++ b/e-util/e-signature.c
@@ -14,9 +14,6 @@
  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  *
  *
- * Authors:
- *		Jeffrey Stedfast <fejj ximian com>
- *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  *
  */
@@ -31,69 +28,327 @@
 #include <libxml/parser.h>
 #include <libxml/xmlmemory.h>
 
+#include <glib/gi18n-lib.h>
 #include <gconf/gconf-client.h>
 
 #include <libedataserver/e-uid.h>
 
 #include "e-signature.h"
 
-static void e_signature_class_init (ESignatureClass *klass);
-static void e_signature_init (ESignature *sig, ESignatureClass *klass);
-static void e_signature_finalize (GObject *object);
+#define E_SIGNATURE_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE \
+	((obj), E_TYPE_SIGNATURE, ESignaturePrivate))
 
-static GObjectClass *parent_class = NULL;
+struct _ESignaturePrivate {
+	gchar *filename;
+	gchar *name;
+	gchar *uid;
 
-GType
-e_signature_get_type (void)
+	gboolean autogenerated;
+	gboolean is_html;
+	gboolean is_script;
+};
+
+enum {
+	PROP_0,
+	PROP_AUTOGENERATED,
+	PROP_FILENAME,
+	PROP_IS_HTML,
+	PROP_IS_SCRIPT,
+	PROP_NAME,
+	PROP_UID
+};
+
+static gpointer parent_class;
+
+static gboolean
+xml_set_bool (xmlNodePtr node,
+              const gchar *name,
+              gboolean *val)
 {
-	static GType type = 0;
+	gboolean v_boolean;
+	gchar *buf;
 
-	if (!type) {
-		GTypeInfo type_info = {
-			sizeof (ESignatureClass),
-			NULL, NULL,
-			(GClassInitFunc) e_signature_class_init,
-			NULL, NULL,
-			sizeof (ESignature),
-			0,
-			(GInstanceInitFunc) e_signature_init,
-		};
+	if ((buf = (gchar *)xmlGetProp (node, (xmlChar *) name))) {
+		v_boolean = (!strcmp (buf, "true") || !strcmp (buf, "yes"));
+		xmlFree (buf);
 
-		type = g_type_register_static (G_TYPE_OBJECT, "ESignature", &type_info, 0);
+		if (v_boolean != *val) {
+			*val = v_boolean;
+			return TRUE;
+		}
 	}
 
-	return type;
+	return FALSE;
 }
 
-static void
-e_signature_class_init (ESignatureClass *klass)
+static gboolean
+xml_set_prop (xmlNodePtr node,
+              const gchar *name,
+              gchar **val)
+{
+	gchar *buf, *new_val;
+
+	buf = (gchar *)xmlGetProp (node, (xmlChar *) name);
+	new_val = g_strdup (buf);
+	xmlFree (buf);
+
+	/* We can use strcmp here whether the value is UTF8 or
+	 * not, since we only care if the bytes changed.
+	 */
+	if (!*val || strcmp (*val, new_val)) {
+		g_free (*val);
+		*val = new_val;
+		return TRUE;
+	} else {
+		g_free (new_val);
+		return FALSE;
+	}
+}
+
+static gboolean
+xml_set_content (xmlNodePtr node,
+                 gchar **val)
 {
-	GObjectClass *object_class = (GObjectClass *) klass;
+	gchar *buf, *new_val;
 
-	parent_class = g_type_class_ref (G_TYPE_OBJECT);
+	buf = (gchar *)xmlNodeGetContent (node);
+        new_val = g_strdup (buf);
+	xmlFree (buf);
 
-	/* virtual method override */
-	object_class->finalize = e_signature_finalize;
+	/* We can use strcmp here whether the value is UTF8 or
+	 * not, since we only care if the bytes changed. */
+	if (!*val || strcmp (*val, new_val)) {
+		g_free (*val);
+		*val = new_val;
+		return TRUE;
+	} else {
+		g_free (new_val);
+		return FALSE;
+	}
 }
 
 static void
-e_signature_init (ESignature *sig, ESignatureClass *klass)
+signature_set_property (GObject *object,
+                        guint property_id,
+                        const GValue *value,
+                        GParamSpec *pspec)
 {
-	;
+	switch (property_id) {
+		case PROP_AUTOGENERATED:
+			e_signature_set_autogenerated (
+				E_SIGNATURE (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_FILENAME:
+			e_signature_set_filename (
+				E_SIGNATURE (object),
+				g_value_get_string (value));
+			return;
+
+		case PROP_IS_HTML:
+			e_signature_set_is_html (
+				E_SIGNATURE (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_IS_SCRIPT:
+			e_signature_set_is_script (
+				E_SIGNATURE (object),
+				g_value_get_boolean (value));
+			return;
+
+		case PROP_NAME:
+			e_signature_set_name (
+				E_SIGNATURE (object),
+				g_value_get_string (value));
+			return;
+
+		case PROP_UID:
+			e_signature_set_uid (
+				E_SIGNATURE (object),
+				g_value_get_string (value));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+signature_get_property (GObject *object,
+                        guint property_id,
+                        GValue *value,
+                        GParamSpec *pspec)
+{
+	switch (property_id) {
+		case PROP_AUTOGENERATED:
+			g_value_set_boolean (
+				value, e_signature_get_autogenerated (
+				E_SIGNATURE (object)));
+			return;
+
+		case PROP_FILENAME:
+			g_value_set_string (
+				value, e_signature_get_filename (
+				E_SIGNATURE (object)));
+			return;
+
+		case PROP_IS_HTML:
+			g_value_set_boolean (
+				value, e_signature_get_is_html (
+				E_SIGNATURE (object)));
+			return;
+
+		case PROP_IS_SCRIPT:
+			g_value_set_boolean (
+				value, e_signature_get_is_script (
+				E_SIGNATURE (object)));
+			return;
+
+		case PROP_NAME:
+			g_value_set_string (
+				value, e_signature_get_name (
+				E_SIGNATURE (object)));
+			return;
+
+		case PROP_UID:
+			g_value_set_string (
+				value, e_signature_get_uid (
+				E_SIGNATURE (object)));
+			return;
+	}
+
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 }
 
 static void
-e_signature_finalize (GObject *object)
+signature_finalize (GObject *object)
 {
-	ESignature *sig = (ESignature *) object;
+	ESignaturePrivate *priv;
 
-	g_free (sig->uid);
-	g_free (sig->name);
-	g_free (sig->filename);
+	priv = E_SIGNATURE_GET_PRIVATE (object);
 
+	g_free (priv->filename);
+	g_free (priv->name);
+	g_free (priv->uid);
+
+	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+static void
+e_signature_class_init (ESignatureClass *class)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	g_type_class_add_private (class, sizeof (ESignaturePrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = signature_set_property;
+	object_class->get_property = signature_get_property;
+	object_class->finalize = signature_finalize;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_AUTOGENERATED,
+		g_param_spec_boolean (
+			"autogenerated",
+			"Autogenerated",
+			NULL,
+			FALSE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_FILENAME,
+		g_param_spec_string (
+			"filename",
+			"Filename",
+			NULL,
+			NULL,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_IS_HTML,
+		g_param_spec_boolean (
+			"is-html",
+			"Is HTML",
+			NULL,
+			FALSE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_IS_SCRIPT,
+		g_param_spec_boolean (
+			"is-script",
+			"Is Script",
+			NULL,
+			FALSE,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_NAME,
+		g_param_spec_string (
+			"name",
+			"Name",
+			NULL,
+			NULL,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+
+	g_object_class_install_property (
+		object_class,
+		PROP_UID,
+		g_param_spec_string (
+			"uid",
+			"UID",
+			NULL,
+			NULL,
+			G_PARAM_READWRITE |
+			G_PARAM_CONSTRUCT));
+}
+
+static void
+e_signature_init (ESignature *signature)
+{
+	signature->priv = E_SIGNATURE_GET_PRIVATE (signature);
+}
+
+GType
+e_signature_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		GTypeInfo type_info = {
+			sizeof (ESignatureClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) e_signature_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,  /* class_data */
+			sizeof (ESignature),
+			0,     /* n_preallocs */
+			(GInstanceInitFunc) e_signature_init,
+			NULL   /* value_table */
+		};
+
+		type = g_type_register_static (
+			G_TYPE_OBJECT, "ESignature", &type_info, 0);
+	}
+
+	return type;
+}
+
 /**
  * e_signature_new:
  *
@@ -106,7 +361,7 @@ e_signature_new (void)
 	ESignature *signature;
 
 	signature = g_object_new (E_TYPE_SIGNATURE, NULL);
-	signature->uid = e_uid_new ();
+	signature->priv->uid = e_uid_new ();
 
 	return signature;
 }
@@ -124,6 +379,7 @@ e_signature_new_from_xml (const gchar *xml)
 	ESignature *signature;
 
 	signature = g_object_new (E_TYPE_SIGNATURE, NULL);
+
 	if (!e_signature_set_from_xml (signature, xml)) {
 		g_object_unref (signature);
 		return NULL;
@@ -132,69 +388,6 @@ e_signature_new_from_xml (const gchar *xml)
 	return signature;
 }
 
-static gboolean
-xml_set_bool (xmlNodePtr node, const gchar *name, gboolean *val)
-{
-	gboolean bool;
-	gchar *buf;
-
-	if ((buf = (gchar *)xmlGetProp (node, (const guchar *)name))) {
-		bool = (!strcmp (buf, "true") || !strcmp (buf, "yes"));
-		xmlFree (buf);
-
-		if (bool != *val) {
-			*val = bool;
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-static gboolean
-xml_set_prop (xmlNodePtr node, const gchar *name, gchar **val)
-{
-	gchar *buf, *new_val;
-
-	buf = (gchar *)xmlGetProp (node, (const guchar *)name);
-	new_val = g_strdup (buf);
-	xmlFree (buf);
-
-	/* We can use strcmp here whether the value is UTF8 or
-	 * not, since we only care if the bytes changed.
-	 */
-	if (!*val || strcmp (*val, new_val)) {
-		g_free (*val);
-		*val = new_val;
-		return TRUE;
-	} else {
-		g_free (new_val);
-		return FALSE;
-	}
-}
-
-static gboolean
-xml_set_content (xmlNodePtr node, gchar **val)
-{
-	gchar *buf, *new_val;
-
-	buf = (gchar *)xmlNodeGetContent (node);
-        new_val = g_strdup (buf);
-	xmlFree (buf);
-
-	/* We can use strcmp here whether the value is UTF8 or
-	 * not, since we only care if the bytes changed.
-	 */
-	if (!*val || strcmp (*val, new_val)) {
-		g_free (*val);
-		*val = new_val;
-		return TRUE;
-	} else {
-		g_free (new_val);
-		return FALSE;
-	}
-}
-
 /**
  * e_signature_uid_from_xml:
  * @xml: an XML signature description
@@ -210,7 +403,7 @@ e_signature_uid_from_xml (const gchar *xml)
 	xmlDocPtr doc;
 	gchar *uid = NULL;
 
-	if (!(doc = xmlParseDoc ((guchar *) xml)))
+	if (!(doc = xmlParseDoc ((xmlChar *) xml)))
 		return NULL;
 
 	node = doc->children;
@@ -243,7 +436,7 @@ e_signature_set_from_xml (ESignature *signature, const gchar *xml)
 	gboolean bool;
 	gchar *buf;
 
-	if (!(doc = xmlParseDoc ((guchar *) xml)))
+	if (!(doc = xmlParseDoc ((xmlChar *) xml)))
 		return FALSE;
 
 	node = doc->children;
@@ -252,18 +445,13 @@ e_signature_set_from_xml (ESignature *signature, const gchar *xml)
 		return FALSE;
 	}
 
-	if (!signature->uid)
-		xml_set_prop (node, "uid", &signature->uid);
+	if (!signature->priv->uid)
+		xml_set_prop (node, "uid", &signature->priv->uid);
 
-	changed |= xml_set_prop (node, "name", &signature->name);
-	changed |= xml_set_bool (node, "auto", &signature->autogen);
+	changed |= xml_set_prop (node, "name", &signature->priv->name);
+	changed |= xml_set_bool (node, "auto", &signature->priv->autogenerated);
 
-	if (signature->autogen) {
-		/* we're done */
-		g_free (signature->filename);
-		signature->filename = NULL;
-		signature->script = FALSE;
-		signature->html = FALSE;
+	if (e_signature_get_autogenerated (signature)) {
 		xmlFreeDoc (doc);
 
 		return changed;
@@ -277,22 +465,22 @@ e_signature_set_from_xml (ESignature *signature, const gchar *xml)
 		bool = FALSE;
 	g_free (buf);
 
-	if (signature->html != bool) {
-		signature->html = bool;
+	if (e_signature_get_is_html (signature) != bool) {
+		e_signature_set_is_html (signature, bool);
 		changed = TRUE;
 	}
 
 	cur = node->children;
 	while (cur) {
 		if (!strcmp ((gchar *)cur->name, "filename")) {
-			changed |= xml_set_content (cur, &signature->filename);
-			changed |= xml_set_bool (cur, "script", &signature->script);
+			changed |= xml_set_content (cur, &signature->priv->filename);
+			changed |= xml_set_bool (cur, "script", &signature->priv->is_script);
 			break;
 		} else if (!strcmp ((gchar *)cur->name, "script")) {
 			/* this is for handling 1.4 signature script definitions */
-			changed |= xml_set_content (cur, &signature->filename);
-			if (!signature->script) {
-				signature->script = TRUE;
+			changed |= xml_set_content (cur, &signature->priv->filename);
+			if (!e_signature_get_is_script (signature)) {
+				e_signature_set_is_script (signature, TRUE);
 				changed = TRUE;
 			}
 			break;
@@ -320,28 +508,42 @@ e_signature_to_xml (ESignature *signature)
 	gchar *tmp;
 	xmlNodePtr root, node;
 	xmlDocPtr doc;
+	const gchar *string;
 	gint n;
 
-	doc = xmlNewDoc ((const guchar *)"1.0");
+	doc = xmlNewDoc ((xmlChar *) "1.0");
 
-	root = xmlNewDocNode (doc, NULL, (const guchar *)"signature", NULL);
+	root = xmlNewDocNode (doc, NULL, (xmlChar *) "signature", NULL);
 	xmlDocSetRootElement (doc, root);
 
-	xmlSetProp (root, (const guchar *)"name", (guchar *)signature->name);
-	xmlSetProp (root, (const guchar *)"uid", (guchar *)signature->uid);
-	xmlSetProp (root, (const guchar *)"auto", (const guchar *)(signature->autogen ? "true" : "false"));
+	string = e_signature_get_name (signature);
+	xmlSetProp (root, (xmlChar *) "name", (xmlChar *) string);
 
-	if (!signature->autogen) {
-		xmlSetProp (root, (const guchar *)"format", (const guchar *)(signature->html ? "text/html" : "text/plain"));
+	string = e_signature_get_uid (signature);
+	xmlSetProp (root, (xmlChar *) "uid", (xmlChar *) string);
 
-		if (signature->filename) {
-			node = xmlNewTextChild (root, NULL, (const guchar *)"filename", (guchar *)signature->filename);
-			if (signature->script)
-				xmlSetProp (node, (const guchar *)"script", (const guchar *)"true");
+	if (e_signature_get_autogenerated (signature))
+		string = "true";
+	else
+		string = "false";
+	xmlSetProp (root, (xmlChar *) "auto", (xmlChar *) string);
+
+	if (!e_signature_get_autogenerated (signature)) {
+		if (e_signature_get_is_html (signature))
+			string = "text/html";
+		else
+			string = "text/plain";
+		xmlSetProp (root, (xmlChar *) "format", (xmlChar *) string);
+
+		string = e_signature_get_filename (signature);
+		if (string != NULL) {
+			node = xmlNewTextChild (root, NULL, (xmlChar *) "filename", (xmlChar *) string);
+			if (e_signature_get_is_script (signature))
+				xmlSetProp (node, (xmlChar *) "script", (xmlChar *) "true");
 		}
 	} else {
 		/* this is to make Evolution-1.4 and older 1.5 versions happy */
-		xmlSetProp (root, (const guchar *)"format", (const guchar *)"text/html");
+		xmlSetProp (root, (xmlChar *) "format", (xmlChar *) "text/html");
 	}
 
 	xmlDocDumpMemory (doc, &xmlbuf, &n);
@@ -356,3 +558,172 @@ e_signature_to_xml (ESignature *signature)
 	return tmp;
 }
 
+gboolean
+e_signature_is_equal (ESignature *signature1,
+                      ESignature *signature2)
+{
+	const gchar *uid1;
+	const gchar *uid2;
+
+	g_return_val_if_fail (E_IS_SIGNATURE (signature1), FALSE);
+	g_return_val_if_fail (E_IS_SIGNATURE (signature2), FALSE);
+
+	/* XXX Simply compares the UIDs.  Not fool-proof. */
+	uid1 = e_signature_get_uid (signature1);
+	uid2 = e_signature_get_uid (signature2);
+
+	return (g_strcmp0 (uid1, uid2) == 0);
+}
+
+gboolean
+e_signature_get_autogenerated (ESignature *signature)
+{
+	g_return_val_if_fail (E_IS_SIGNATURE (signature), FALSE);
+
+	return signature->priv->autogenerated;
+}
+
+void
+e_signature_set_autogenerated (ESignature *signature,
+                               gboolean autogenerated)
+{
+	g_return_if_fail (E_IS_SIGNATURE (signature));
+
+	if (signature->priv->autogenerated == autogenerated)
+		return;
+
+	signature->priv->autogenerated = autogenerated;
+
+	/* Autogenerated flags overrides several properties. */
+	g_object_freeze_notify (G_OBJECT (signature));
+	g_object_notify (G_OBJECT (signature), "autogenerated");
+	g_object_notify (G_OBJECT (signature), "filename");
+	g_object_notify (G_OBJECT (signature), "is-html");
+	g_object_notify (G_OBJECT (signature), "is-script");
+	g_object_notify (G_OBJECT (signature), "name");
+	g_object_thaw_notify (G_OBJECT (signature));
+}
+
+const gchar *
+e_signature_get_filename (ESignature *signature)
+{
+	g_return_val_if_fail (E_IS_SIGNATURE (signature), NULL);
+
+	/* Autogenerated flags overrides the filename property. */
+	if (e_signature_get_autogenerated (signature))
+		return NULL;
+
+	return signature->priv->filename;
+}
+
+void
+e_signature_set_filename (ESignature *signature,
+                          const gchar *filename)
+{
+	g_return_if_fail (E_IS_SIGNATURE (signature));
+
+	g_free (signature->priv->filename);
+	signature->priv->filename = g_strdup (filename);
+
+	g_object_notify (G_OBJECT (signature), "filename");
+}
+
+gboolean
+e_signature_get_is_html (ESignature *signature)
+{
+	g_return_val_if_fail (E_IS_SIGNATURE (signature), FALSE);
+
+	/* Autogenerated flag overrides the is-html property. */
+	if (e_signature_get_autogenerated (signature))
+		return FALSE;
+
+	return signature->priv->is_html;
+}
+
+void
+e_signature_set_is_html (ESignature *signature,
+                         gboolean is_html)
+{
+	g_return_if_fail (E_IS_SIGNATURE (signature));
+
+	if (signature->priv->is_html == is_html)
+		return;
+
+	signature->priv->is_html = is_html;
+
+	g_object_notify (G_OBJECT (signature), "is-html");
+}
+
+gboolean
+e_signature_get_is_script (ESignature *signature)
+{
+	g_return_val_if_fail (E_IS_SIGNATURE (signature), FALSE);
+
+	/* Autogenerated flags overrides the is-script property. */
+	if (e_signature_get_autogenerated (signature))
+		return FALSE;
+
+	return signature->priv->is_script;
+}
+
+void
+e_signature_set_is_script (ESignature *signature,
+                           gboolean is_script)
+{
+	g_return_if_fail (E_IS_SIGNATURE (signature));
+
+	if (signature->priv->is_script == is_script)
+		return;
+
+	signature->priv->is_script = is_script;
+
+	g_object_notify (G_OBJECT (signature), "is-script");
+}
+
+const gchar *
+e_signature_get_name (ESignature *signature)
+{
+	g_return_val_if_fail (E_IS_SIGNATURE (signature), NULL);
+
+	/* Autogenerated flag overrides the name property. */
+	if (e_signature_get_autogenerated (signature))
+		return _("Autogenerated");
+
+	return signature->priv->name;
+}
+
+void
+e_signature_set_name (ESignature *signature,
+                      const gchar *name)
+{
+	g_return_if_fail (E_IS_SIGNATURE (signature));
+
+	g_free (signature->priv->name);
+	signature->priv->name = g_strdup (name);
+
+	g_object_notify (G_OBJECT (signature), "name");
+}
+
+const gchar *
+e_signature_get_uid (ESignature *signature)
+{
+	g_return_val_if_fail (E_IS_SIGNATURE (signature), NULL);
+
+	return signature->priv->uid;
+}
+
+void
+e_signature_set_uid (ESignature *signature,
+                     const gchar *uid)
+{
+	g_return_if_fail (E_IS_SIGNATURE (signature));
+
+	g_free (signature->priv->uid);
+
+	if (uid == NULL)
+		signature->priv->uid = e_uid_new ();
+	else
+		signature->priv->uid = g_strdup (uid);
+
+	g_object_notify (G_OBJECT (signature), "uid");
+}
diff --git a/e-util/e-signature.h b/e-util/e-signature.h
index 3dced19..fad1faf 100644
--- a/e-util/e-signature.h
+++ b/e-util/e-signature.h
@@ -14,57 +14,77 @@
  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  *
  *
- * Authors:
- *		Jeffrey Stedfast <fejj ximian com>
- *
  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  *
  */
 
-#ifndef __E_SIGNATURE_H__
-#define __E_SIGNATURE_H__
+#ifndef E_SIGNATURE_H
+#define E_SIGNATURE_H
 
 #include <glib-object.h>
 
-G_BEGIN_DECLS
+/* Standard GObject macros */
+#define E_TYPE_SIGNATURE \
+	(e_signature_get_type ())
+#define E_SIGNATURE(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), E_TYPE_SIGNATURE, ESignature))
+#define E_SIGNATURE_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), E_TYPE_SIGNATURE, ESignatureClass))
+#define E_IS_SIGNATURE(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), E_TYPE_SIGNATURE))
+#define E_IS_SIGNATURE_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), E_TYPE_SIGNATURE))
+#define E_SIGNATURE_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), E_TYPE_SIGNATURE, ESignatureClass))
 
-#define E_TYPE_SIGNATURE            (e_signature_get_type ())
-#define E_SIGNATURE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_SIGNATURE, ESignature))
-#define E_SIGNATURE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_SIGNATURE, ESignatureClass))
-#define E_IS_SIGNATURE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_SIGNATURE))
-#define E_IS_SIGNATURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_SIGNATURE))
+G_BEGIN_DECLS
 
 typedef struct _ESignature ESignature;
 typedef struct _ESignatureClass ESignatureClass;
+typedef struct _ESignaturePrivate ESignaturePrivate;
 
 struct _ESignature {
-	GObject parent_object;
-
-	gboolean autogen;
-	gboolean script;
-	gboolean html;
-
-	gchar *filename;
-	gchar *name;
-	gchar *uid;
+	GObject parent;
+	ESignaturePrivate *priv;
 };
 
 struct _ESignatureClass {
 	GObjectClass parent_class;
-
 };
 
-GType e_signature_get_type (void);
-
-ESignature *e_signature_new (void);
-ESignature *e_signature_new_from_xml (const gchar *xml);
-
-gchar *e_signature_uid_from_xml (const gchar *xml);
-
-gboolean e_signature_set_from_xml (ESignature *sig, const gchar *xml);
-
-gchar *e_signature_to_xml (ESignature *sig);
+GType		e_signature_get_type		(void);
+ESignature *	e_signature_new			(void);
+ESignature *	e_signature_new_from_xml	(const gchar *xml);
+gchar *		e_signature_uid_from_xml	(const gchar *xml);
+gboolean	e_signature_set_from_xml	(ESignature *signature,
+						 const gchar *xml);
+gchar *		e_signature_to_xml		(ESignature *signature);
+gboolean	e_signature_is_equal		(ESignature *signature1,
+						 ESignature *signature2);
+gboolean	e_signature_get_autogenerated	(ESignature *signature);
+void		e_signature_set_autogenerated	(ESignature *signature,
+						 gboolean autogenerated);
+const gchar *	e_signature_get_filename	(ESignature *signature);
+void		e_signature_set_filename	(ESignature *signature,
+						 const gchar *filename);
+gboolean	e_signature_get_is_html		(ESignature *signature);
+void		e_signature_set_is_html		(ESignature *signature,
+						 gboolean is_html);
+gboolean	e_signature_get_is_script	(ESignature *signature);
+void		e_signature_set_is_script	(ESignature *signature,
+						 gboolean is_script);
+const gchar *	e_signature_get_name		(ESignature *signature);
+void		e_signature_set_name		(ESignature *signature,
+						 const gchar *name);
+const gchar *	e_signature_get_uid		(ESignature *signature);
+void		e_signature_set_uid		(ESignature *signature,
+						 const gchar *uid);
 
 G_END_DECLS
 
-#endif /* __E_SIGNATURE_H__ */
+#endif /* E_SIGNATURE_H */
diff --git a/mail/em-account-editor.c b/mail/em-account-editor.c
index 6c55a65..6ba4077 100644
--- a/mail/em-account-editor.c
+++ b/mail/em-account-editor.c
@@ -787,11 +787,16 @@ emae_signature_added (ESignatureList *signatures, ESignature *sig, EMAccountEdit
 {
 	GtkTreeModel *model;
 	GtkTreeIter iter;
+	const gchar *name;
+	const gchar *uid;
+
+	name = e_signature_get_name (sig);
+	uid = e_signature_get_uid (sig);
 
 	model = gtk_combo_box_get_model (emae->priv->signatures_dropdown);
 
 	gtk_list_store_append ((GtkListStore *)model, &iter);
-	gtk_list_store_set ((GtkListStore *)model, &iter, 0, sig->autogen?_("Autogenerated"):sig->name, 1, sig->uid, -1);
+	gtk_list_store_set ((GtkListStore *)model, &iter, 0, name, 1, uid, -1);
 
 	gtk_combo_box_set_active (emae->priv->signatures_dropdown, gtk_tree_model_iter_n_children (model, NULL)-1);
 }
@@ -808,10 +813,13 @@ emae_signature_get_iter (EMAccountEditor *emae, ESignature *sig, GtkTreeModel **
 		return FALSE;
 
 	do {
+		const gchar *signature_uid;
 		gchar *uid;
 
+		signature_uid = e_signature_get_uid (sig);
+
 		gtk_tree_model_get (model, iter, 1, &uid, -1);
-		if (uid && !strcmp (uid, sig->uid))
+		if (uid && !strcmp (uid, signature_uid))
 			found = TRUE;
 		g_free (uid);
 	} while (!found && gtk_tree_model_iter_next (model, iter));
@@ -834,9 +842,12 @@ emae_signature_changed (ESignatureList *signatures, ESignature *sig, EMAccountEd
 {
 	GtkTreeIter iter;
 	GtkTreeModel *model;
+	const gchar *name;
+
+	name = e_signature_get_name (sig);
 
 	if (emae_signature_get_iter (emae, sig, &model, &iter))
-		gtk_list_store_set ((GtkListStore *)model, &iter, 0, sig->autogen?_("Autogenerated"):sig->name, -1);
+		gtk_list_store_set ((GtkListStore *)model, &iter, 0, name, -1);
 }
 
 static void
@@ -923,11 +934,16 @@ emae_setup_signatures (EMAccountEditor *emae, GladeXML *xml)
 	it = e_list_get_iterator ((EList *) signatures);
 	while (e_iterator_is_valid (it)) {
 		ESignature *sig = (ESignature *)e_iterator_get (it);
+		const gchar *name;
+		const gchar *uid;
+
+		name = e_signature_get_name (sig);
+		uid = e_signature_get_uid (sig);
 
 		gtk_list_store_append (store, &iter);
-		gtk_list_store_set (store, &iter, 0, sig->autogen?_("Autogenerated"):sig->name, 1, sig->uid, -1);
+		gtk_list_store_set (store, &iter, 0, name, 1, uid, -1);
 
-		if (current && !strcmp (current, sig->uid))
+		if (current && !strcmp (current, uid))
 			active = i;
 
 		e_iterator_next (it);
diff --git a/mail/em-composer-prefs.c b/mail/em-composer-prefs.c
new file mode 100644
index 0000000..0a7312e
--- /dev/null
+++ b/mail/em-composer-prefs.c
@@ -0,0 +1,1080 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *		Jeffrey Stedfast <fejj ximian com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "e-util/e-signature.h"
+#include "e-util/e-signature-list.h"
+#include "e-util/gconf-bridge.h"
+
+#include "em-composer-prefs.h"
+#include "composer/e-msg-composer.h"
+
+#include <bonobo/bonobo-generic-factory.h>
+
+#include <camel/camel-iconv.h>
+
+#include <misc/e-gui-utils.h>
+
+#include <glib/gstdio.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <gtkhtml/gtkhtml.h>
+#include <editor/gtkhtml-spell-language.h>
+
+#include "misc/e-charset-picker.h"
+#include "e-util/e-error.h"
+#include "e-util/e-util-private.h"
+
+#include "mail-config.h"
+#include "mail-signature-editor.h"
+#include "em-config.h"
+
+static gpointer parent_class;
+
+static void
+composer_prefs_dispose (GObject *object)
+{
+	EMComposerPrefs *prefs = (EMComposerPrefs *) object;
+	ESignatureList *signature_list;
+
+	signature_list = mail_config_get_signatures ();
+
+	if (prefs->sig_added_id != 0) {
+		g_signal_handler_disconnect (
+			signature_list, prefs->sig_added_id);
+		prefs->sig_added_id = 0;
+	}
+
+	if (prefs->sig_removed_id != 0) {
+		g_signal_handler_disconnect (
+			signature_list, prefs->sig_removed_id);
+		prefs->sig_removed_id = 0;
+	}
+
+	if (prefs->sig_changed_id != 0) {
+		g_signal_handler_disconnect (
+			signature_list, prefs->sig_changed_id);
+		prefs->sig_changed_id = 0;
+	}
+
+	/* Chain up to parent's dispose() method. */
+	G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+composer_prefs_finalize (GObject *object)
+{
+	EMComposerPrefs *prefs = (EMComposerPrefs *) object;
+
+	g_object_unref (prefs->gui);
+
+	g_hash_table_destroy (prefs->sig_hash);
+
+	/* Chain up to parent's finalize() method. */
+        G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+composer_prefs_class_init (EMComposerPrefsClass *class)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (class);
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->dispose = composer_prefs_dispose;
+	object_class->finalize = composer_prefs_finalize;
+}
+
+static void
+composer_prefs_init (EMComposerPrefs *prefs)
+{
+	prefs->sig_hash = g_hash_table_new_full (
+		g_direct_hash, g_direct_equal,
+		(GDestroyNotify) NULL,
+		(GDestroyNotify) gtk_tree_row_reference_free);
+}
+
+GType
+em_composer_prefs_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		static const GTypeInfo type_info = {
+			sizeof (EMComposerPrefsClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) composer_prefs_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,  /* class_data */
+			sizeof (EMComposerPrefs),
+			0,     /* n_allocs */
+			(GInstanceInitFunc) composer_prefs_init,
+			NULL   /* value_table */
+		};
+
+		type = g_type_register_static (
+			GTK_TYPE_VBOX, "EMComposerPrefs", &type_info, 0);
+	}
+
+	return type;
+}
+
+static void
+sig_load_preview (EMComposerPrefs *prefs,
+                  ESignature *signature)
+{
+	GtkHTML *html;
+	gchar *str;
+	const gchar *filename;
+	gboolean is_html;
+
+	html = prefs->sig_preview;
+
+	if (signature == NULL) {
+		gtk_html_load_from_string (html, " ", 1);
+		return;
+	}
+
+	filename = e_signature_get_filename (signature);
+	is_html = e_signature_get_is_html (signature);
+
+	if (e_signature_get_is_script (signature))
+		str = mail_config_signature_run_script (filename);
+	else
+		str = e_msg_composer_get_sig_file_content (filename, is_html);
+	if (!str || !*str) {
+		/* make html stream happy and write at least one character */
+		g_free (str);
+		str = g_strdup (" ");
+	}
+
+	if (is_html)
+		gtk_html_load_from_string (html, str, strlen (str));
+	else {
+		GtkHTMLStream *stream;
+		gint len;
+
+		len = strlen (str);
+		stream = gtk_html_begin_content (html, "text/html; charset=utf-8");
+		gtk_html_write (html, stream, "<PRE>", 5);
+		if (len)
+			gtk_html_write (html, stream, str, len);
+		gtk_html_write (html, stream, "</PRE>", 6);
+		gtk_html_end (html, stream, GTK_HTML_STREAM_OK);
+	}
+
+	g_free (str);
+}
+
+static void
+signature_added (ESignatureList *signature_list,
+                 ESignature *signature,
+                 EMComposerPrefs *prefs)
+{
+	GtkTreeRowReference *row;
+	GtkTreeModel *model;
+	GtkTreePath *path;
+	GtkTreeIter iter;
+	const gchar *name;
+
+	/* autogen signature is special */
+	if (e_signature_get_autogenerated (signature))
+		return;
+
+	name = e_signature_get_name (signature);
+
+	model = gtk_tree_view_get_model (prefs->sig_list);
+	gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+	gtk_list_store_set (
+		GTK_LIST_STORE (model), &iter,
+		0, name, 1, signature, -1);
+
+	path = gtk_tree_model_get_path (model, &iter);
+	row = gtk_tree_row_reference_new (model, path);
+	gtk_tree_path_free (path);
+
+	g_hash_table_insert (prefs->sig_hash, signature, row);
+}
+
+static void
+signature_removed (ESignatureList *signature_list,
+                   ESignature *signature,
+                   EMComposerPrefs *prefs)
+{
+	GtkTreeRowReference *row;
+	GtkTreeModel *model;
+	GtkTreePath *path;
+	GtkTreeIter iter;
+
+	if (!(row = g_hash_table_lookup (prefs->sig_hash, signature)))
+		return;
+
+	model = gtk_tree_view_get_model (prefs->sig_list);
+	path = gtk_tree_row_reference_get_path (row);
+	g_hash_table_remove (prefs->sig_hash, signature);
+
+	if (!gtk_tree_model_get_iter (model, &iter, path)) {
+		gtk_tree_path_free (path);
+		return;
+	}
+
+	gtk_list_store_remove ((GtkListStore *) model, &iter);
+}
+
+static void
+signature_changed (ESignatureList *signature_list,
+                   ESignature *signature,
+                   EMComposerPrefs *prefs)
+{
+	GtkTreeSelection *selection;
+	GtkTreeRowReference *row;
+	GtkTreeModel *model;
+	GtkTreePath *path;
+	GtkTreeIter iter;
+	ESignature *cur;
+	const gchar *name;
+
+	if (!(row = g_hash_table_lookup (prefs->sig_hash, signature)))
+		return;
+
+	model = gtk_tree_view_get_model (prefs->sig_list);
+	path = gtk_tree_row_reference_get_path (row);
+
+	if (!gtk_tree_model_get_iter (model, &iter, path)) {
+		gtk_tree_path_free (path);
+		return;
+	}
+
+	gtk_tree_path_free (path);
+
+	name = e_signature_get_name (signature);
+	gtk_list_store_set ((GtkListStore *) model, &iter, 0, name, -1);
+
+	selection = gtk_tree_view_get_selection (prefs->sig_list);
+	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+		gtk_tree_model_get (model, &iter, 1, &cur, -1);
+		if (cur == signature)
+			sig_load_preview (prefs, signature);
+	}
+}
+
+static void
+sig_edit_cb (GtkWidget *widget, EMComposerPrefs *prefs)
+{
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkWidget *parent;
+	GtkTreeIter iter;
+	ESignature *signature;
+	const gchar *filename;
+	const gchar *name;
+
+	selection = gtk_tree_view_get_selection (prefs->sig_list);
+	if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+		return;
+
+	gtk_tree_model_get (model, &iter, 1, &signature, -1);
+
+	filename = e_signature_get_filename (signature);
+	name = e_signature_get_name (signature);
+
+	if (!e_signature_get_is_script (signature)) {
+		GtkWidget *editor;
+
+		filename = e_signature_get_filename (signature);
+
+		/* normal signature */
+		if (filename == NULL || *filename == '\0') {
+			e_signature_set_filename (signature, _("Unnamed"));
+			filename = e_signature_get_filename (signature);
+		}
+
+		editor = e_signature_editor_new ();
+		e_signature_editor_set_signature (
+			E_SIGNATURE_EDITOR (editor), signature);
+
+		parent = gtk_widget_get_toplevel ((GtkWidget *) prefs);
+		if (GTK_WIDGET_TOPLEVEL (parent))
+			gtk_window_set_transient_for (
+				GTK_WINDOW (editor), GTK_WINDOW (parent));
+
+		gtk_widget_show (editor);
+	} else {
+		/* signature script */
+		GtkWidget *entry;
+
+		entry = glade_xml_get_widget (prefs->sig_script_gui, "filechooserbutton_add_script");
+		gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (entry), filename);
+
+		entry = glade_xml_get_widget (prefs->sig_script_gui, "entry_add_script_name");
+		gtk_entry_set_text (GTK_ENTRY (entry), name);
+
+		g_object_set_data ((GObject *) entry, "sig", signature);
+
+		gtk_window_present ((GtkWindow *) prefs->sig_script_dialog);
+	}
+}
+
+void
+em_composer_prefs_new_signature (GtkWindow *parent,
+                                 gboolean html_mode)
+{
+	GtkWidget *editor;
+
+	editor = e_signature_editor_new ();
+	gtkhtml_editor_set_html_mode (GTKHTML_EDITOR (editor), html_mode);
+	gtk_window_set_transient_for (GTK_WINDOW (editor), parent);
+	gtk_widget_show (editor);
+}
+
+static void
+sig_delete_cb (GtkWidget *widget, EMComposerPrefs *prefs)
+{
+	GtkTreeSelection *selection;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	ESignature *signature;
+
+	selection = gtk_tree_view_get_selection (prefs->sig_list);
+
+	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+		gtk_tree_model_get (model, &iter, 1, &signature, -1);
+		mail_config_remove_signature (signature);
+	}
+	gtk_widget_grab_focus ((GtkWidget *)prefs->sig_list);
+}
+
+static void
+sig_add_cb (GtkWidget *widget, EMComposerPrefs *prefs)
+{
+	gboolean send_html;
+	GtkWidget *parent;
+
+	send_html = gconf_client_get_bool (
+		mail_config_get_gconf_client (),
+		"/apps/evolution/mail/composer/send_html", NULL);
+
+	parent = gtk_widget_get_toplevel (GTK_WIDGET (prefs));
+	parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+	em_composer_prefs_new_signature (GTK_WINDOW (parent), send_html);
+	gtk_widget_grab_focus (GTK_WIDGET (prefs->sig_list));
+}
+
+static void
+sig_add_script_response (GtkWidget *widget, gint button, EMComposerPrefs *prefs)
+{
+	gchar *script, **argv = NULL;
+	GtkWidget *entry;
+	const gchar *name;
+	gint argc;
+
+	if (button == GTK_RESPONSE_ACCEPT) {
+		entry = glade_xml_get_widget (prefs->sig_script_gui, "filechooserbutton_add_script");
+		script = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (entry));
+
+		entry = glade_xml_get_widget (prefs->sig_script_gui, "entry_add_script_name");
+		name = gtk_entry_get_text (GTK_ENTRY (entry));
+		if (script && *script && g_shell_parse_argv (script, &argc, &argv, NULL)) {
+			struct stat st;
+
+			if (g_stat (argv[0], &st) == 0 && S_ISREG (st.st_mode) && g_access (argv[0], X_OK) == 0) {
+				ESignature *signature;
+
+				if ((signature = g_object_get_data ((GObject *) entry, "sig"))) {
+					/* we're just editing an existing signature script */
+					e_signature_set_name (signature, name);
+					e_signature_set_filename (signature, script);
+					e_signature_list_change (mail_config_get_signatures (), signature);
+				} else {
+					signature = mail_config_signature_new (script, TRUE, TRUE);
+					e_signature_set_name (signature, name);
+
+					e_signature_list_add (mail_config_get_signatures (), signature);
+					g_object_unref (signature);
+				}
+
+				mail_config_save_signatures();
+
+				gtk_widget_hide (prefs->sig_script_dialog);
+				g_strfreev (argv);
+				g_free (script);
+
+				return;
+			}
+		}
+
+		e_error_run((GtkWindow *)prefs->sig_script_dialog, "mail:signature-notscript", argv ? argv[0] : script, NULL);
+		g_strfreev (argv);
+		g_free (script);
+		return;
+	}
+
+	gtk_widget_hide (widget);
+}
+
+static void
+sig_add_script_cb (GtkWidget *widget, EMComposerPrefs *prefs)
+{
+	GtkWidget *entry;
+
+	entry = glade_xml_get_widget (prefs->sig_script_gui, "entry_add_script_name");
+	gtk_entry_set_text (GTK_ENTRY (entry), _("Unnamed"));
+
+	g_object_set_data ((GObject *) entry, "sig", NULL);
+
+	gtk_window_present ((GtkWindow *) prefs->sig_script_dialog);
+}
+
+static void
+sig_selection_changed (GtkTreeSelection *selection,
+                       EMComposerPrefs *prefs)
+{
+	ESignature *signature;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean valid;
+
+	valid = gtk_tree_selection_get_selected (selection, &model, &iter);
+
+	if (valid) {
+		gtk_tree_model_get (model, &iter, 1, &signature, -1);
+		sig_load_preview (prefs, signature);
+	} else
+		sig_load_preview (prefs, NULL);
+
+	gtk_widget_set_sensitive (GTK_WIDGET (prefs->sig_delete), valid);
+	gtk_widget_set_sensitive (GTK_WIDGET (prefs->sig_edit), valid);
+}
+
+static void
+sig_fill_list (EMComposerPrefs *prefs)
+{
+	ESignatureList *signature_list;
+	GtkTreeModel *model;
+	EIterator *iterator;
+
+	model = gtk_tree_view_get_model (prefs->sig_list);
+	gtk_list_store_clear (GTK_LIST_STORE (model));
+
+	signature_list = mail_config_get_signatures ();
+	iterator = e_list_get_iterator ((EList *) signature_list);
+
+	while (e_iterator_is_valid (iterator)) {
+		ESignature *signature;
+
+		signature = (ESignature *) e_iterator_get (iterator);
+		signature_added (signature_list, signature, prefs);
+
+		e_iterator_next (iterator);
+	}
+
+	g_object_unref (iterator);
+
+	gtk_widget_set_sensitive (GTK_WIDGET (prefs->sig_edit), FALSE);
+	gtk_widget_set_sensitive (GTK_WIDGET (prefs->sig_delete), FALSE);
+
+	prefs->sig_added_id = g_signal_connect (
+		signature_list, "signature-added",
+		G_CALLBACK (signature_added), prefs);
+
+	prefs->sig_removed_id = g_signal_connect (
+		signature_list, "signature-removed",
+		G_CALLBACK (signature_removed), prefs);
+
+	prefs->sig_changed_id = g_signal_connect (
+		signature_list, "signature-changed",
+		G_CALLBACK (signature_changed), prefs);
+}
+
+static void
+url_requested (GtkHTML *html,
+               const gchar *url,
+               GtkHTMLStream *handle)
+{
+	GtkHTMLStreamStatus status;
+	gchar buf[128];
+	gssize size;
+	gint fd;
+	gchar *filename;
+
+	if (strncmp (url, "file:", 5) == 0)
+		filename = g_filename_from_uri (url, NULL, NULL);
+	else
+		filename = g_strdup (url);
+	fd = g_open (filename, O_RDONLY | O_BINARY, 0);
+	g_free (filename);
+
+	status = GTK_HTML_STREAM_OK;
+	if (fd != -1) {
+		while ((size = read (fd, buf, sizeof (buf)))) {
+			if (size == -1) {
+				status = GTK_HTML_STREAM_ERROR;
+				break;
+			} else
+				gtk_html_write (html, handle, buf, size);
+		}
+	} else
+		status = GTK_HTML_STREAM_ERROR;
+
+	gtk_html_end (html, handle, status);
+	if (fd > 0)
+		close (fd);
+}
+
+static void
+spell_color_set (GtkColorButton *color_button,
+                 EMComposerPrefs *prefs)
+{
+	GConfClient *client;
+	const gchar *key;
+	GdkColor color;
+	gchar *string;
+
+	gtk_color_button_get_color (color_button, &color);
+	string = gdk_color_to_string (&color);
+
+	client = mail_config_get_gconf_client ();
+	key = "/apps/evolution/mail/composer/spell_color";
+	gconf_client_set_string (client, key, string, NULL);
+
+	g_free (string);
+}
+
+static void
+spell_language_toggled_cb (GtkCellRendererToggle *renderer,
+                           const gchar *path_string,
+                           EMComposerPrefs *prefs)
+{
+	GtkTreeModel *model;
+	GtkTreePath *path;
+	GtkTreeIter iter;
+	gboolean active;
+	gboolean valid;
+
+	model = prefs->language_model;
+
+	/* Convert the path string to a tree iterator. */
+	path = gtk_tree_path_new_from_string (path_string);
+	valid = gtk_tree_model_get_iter (model, &iter, path);
+	gtk_tree_path_free (path);
+	g_return_if_fail (valid);
+
+	/* Toggle the active state. */
+	gtk_tree_model_get (model, &iter, 0, &active, -1);
+	gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, !active, -1);
+}
+
+static void
+spell_language_save (EMComposerPrefs *prefs)
+{
+	GList *spell_languages = NULL;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	gboolean valid;
+
+	model = prefs->language_model;
+
+	/* Build a list of active spell languages. */
+	valid = gtk_tree_model_get_iter_first (model, &iter);
+	while (valid) {
+		const GtkhtmlSpellLanguage *language;
+		gboolean active;
+
+		gtk_tree_model_get (
+			model, &iter, 0, &active, 2, &language, -1);
+
+		if (active)
+			spell_languages = g_list_prepend (
+				spell_languages, (gpointer) language);
+
+		valid = gtk_tree_model_iter_next (model, &iter);
+	}
+	spell_languages = g_list_reverse (spell_languages);
+
+	/* Update the GConf value. */
+	e_save_spell_languages (spell_languages);
+
+	g_list_free (spell_languages);
+}
+
+static void
+spell_setup (EMComposerPrefs *prefs)
+{
+	const GList *available_languages;
+	GList *active_languages;
+	GConfClient *client;
+	GtkListStore *store;
+	GdkColor color;
+	const gchar *key;
+	gchar *string;
+
+	client = mail_config_get_gconf_client ();
+	store = GTK_LIST_STORE (prefs->language_model);
+	available_languages = gtkhtml_spell_language_get_available ();
+
+	active_languages = e_load_spell_languages ();
+
+	/* Populate the GtkListStore. */
+	while (available_languages != NULL) {
+		const GtkhtmlSpellLanguage *language;
+		GtkTreeIter tree_iter;
+		const gchar *name;
+		gboolean active;
+
+		language = available_languages->data;
+		name = gtkhtml_spell_language_get_name (language);
+		active = (g_list_find (active_languages, language) != NULL);
+
+		gtk_list_store_append (store, &tree_iter);
+
+		gtk_list_store_set (
+			store, &tree_iter,
+			0, active, 1, name, 2, language, -1);
+
+		available_languages = available_languages->next;
+	}
+
+	g_list_free (active_languages);
+
+	key = "/apps/evolution/mail/composer/spell_color";
+	string = gconf_client_get_string (client, key, NULL);
+	if (string == NULL || !gdk_color_parse (string, &color))
+		gdk_color_parse ("Red", &color);
+	gtk_color_button_set_color (GTK_COLOR_BUTTON (prefs->color), &color);
+
+	g_signal_connect (
+		prefs->color, "color_set",
+		G_CALLBACK (spell_color_set), prefs);
+}
+
+static gint
+reply_style_new_order (gint style_id,
+                              gboolean from_enum_to_option_id)
+{
+	gint values[] = {
+		MAIL_CONFIG_REPLY_ATTACH, 0,
+		MAIL_CONFIG_REPLY_OUTLOOK, 1,
+		MAIL_CONFIG_REPLY_QUOTED, 2,
+		MAIL_CONFIG_REPLY_DO_NOT_QUOTE, 3,
+		-1, -1};
+	gint ii;
+
+	for (ii = from_enum_to_option_id ? 0 : 1; values[ii] != -1; ii += 2) {
+		if (values[ii] == style_id)
+			return values [from_enum_to_option_id ? ii + 1 : ii - 1];
+	}
+
+	return style_id;
+}
+
+static void
+style_changed (GtkComboBox *combobox, const gchar *key)
+{
+	GConfClient *client;
+	gint style;
+
+	client = mail_config_get_gconf_client ();
+	style = gtk_combo_box_get_active (combobox);
+	g_return_if_fail (style >= 0);
+
+	if (g_str_has_suffix (key, "/reply_style"))
+		style = reply_style_new_order (style, FALSE);
+
+	gconf_client_set_int (client, key, style, NULL);
+}
+
+static void
+charset_activate (GtkWidget *item,
+                  EMComposerPrefs *prefs)
+{
+	GConfClient *client;
+	GtkWidget *menu;
+	gchar *string;
+
+	client = mail_config_get_gconf_client ();
+	menu = gtk_option_menu_get_menu (prefs->charset);
+	string = e_charset_picker_get_charset (menu);
+
+	if (string == NULL)
+		string = g_strdup (camel_iconv_locale_charset ());
+
+	gconf_client_set_string (
+		client, "/apps/evolution/mail/composer/charset",
+		string, NULL);
+
+	g_free (string);
+}
+
+static void
+option_menu_connect (EMComposerPrefs *prefs,
+                     GtkOptionMenu *omenu,
+                     GCallback callback,
+                     const gchar *key)
+{
+	GConfClient *client;
+	GtkWidget *menu;
+	GList *list;
+
+	client = mail_config_get_gconf_client ();
+	menu = gtk_option_menu_get_menu (omenu);
+	list = GTK_MENU_SHELL (menu)->children;
+
+	while (list != NULL) {
+		GtkWidget *widget = list->data;
+
+		g_object_set_data (G_OBJECT (widget), "key", (gpointer) key);
+		g_signal_connect (widget, "activate", callback, prefs);
+		list = list->next;
+	}
+
+	if (!gconf_client_key_is_writable (client, key, NULL))
+		gtk_widget_set_sensitive (GTK_WIDGET (omenu), FALSE);
+}
+
+static GtkWidget *
+emcp_widget_glade (EConfig *ec,
+                   EConfigItem *item,
+                   GtkWidget *parent,
+                   GtkWidget *old,
+                   gpointer data)
+{
+	EMComposerPrefs *prefs = data;
+
+	return glade_xml_get_widget (prefs->gui, item->label);
+}
+
+/* plugin meta-data */
+static EMConfigItem emcp_items[] = {
+	{ E_CONFIG_BOOK, (gchar *) "", (gchar *) "composer_toplevel", emcp_widget_glade },
+	{ E_CONFIG_PAGE, (gchar *) "00.general", (gchar *) "vboxGeneral", emcp_widget_glade },
+	{ E_CONFIG_SECTION, (gchar *) "00.general/00.behavior", (gchar *) "vboxBehavior", emcp_widget_glade },
+	{ E_CONFIG_SECTION, (gchar *) "00.general/10.alerts", (gchar *) "vboxAlerts", emcp_widget_glade },
+	{ E_CONFIG_PAGE, (gchar *) "10.signatures", (gchar *) "vboxSignatures", emcp_widget_glade },
+	/* signature/signatures and signature/preview parts not usable */
+
+	{ E_CONFIG_PAGE, (gchar *) "20.spellcheck", (gchar *) "vboxSpellChecking", emcp_widget_glade },
+	{ E_CONFIG_SECTION, (gchar *) "20.spellcheck/00.languages", (gchar *) "vbox178", emcp_widget_glade },
+	{ E_CONFIG_SECTION, (gchar *) "20.spellcheck/00.options", (gchar *) "vboxOptions", emcp_widget_glade },
+};
+
+static void
+emcp_free (EConfig *ec, GSList *items, gpointer data)
+{
+	/* the prefs data is freed automagically */
+	g_slist_free (items);
+}
+
+static gboolean
+signature_key_press_cb (GtkTreeView *tree_view,
+                        GdkEventKey *event,
+                        EMComposerPrefs *prefs)
+{
+	/* No need to care about anything other than DEL key */
+	if (event->keyval == GDK_Delete) {
+		sig_delete_cb (GTK_WIDGET (tree_view), prefs);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static gboolean
+sig_tree_event_cb (GtkTreeView *tree_view,
+                   GdkEvent *event,
+                   EMComposerPrefs *prefs)
+{
+	if (event->type == GDK_2BUTTON_PRESS) {
+		sig_edit_cb (GTK_WIDGET (tree_view), prefs);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static void
+em_composer_prefs_construct (EMComposerPrefs *prefs)
+{
+	GtkWidget *toplevel, *widget, *menu, *info_pixmap;
+	GtkDialog *dialog;
+	GladeXML *gui;
+	GtkTreeView *view;
+	GtkListStore *store;
+	GtkTreeSelection *selection;
+	GtkCellRenderer *renderer;
+	GConfBridge *bridge;
+	GConfClient *client;
+	const gchar *key;
+	gint style;
+	gchar *buf;
+	EMConfig *ec;
+	EMConfigTargetPrefs *target;
+	GSList *l;
+	gint i;
+	gchar *gladefile;
+	gboolean sensitive;
+
+	bridge = gconf_bridge_get ();
+	client = mail_config_get_gconf_client ();
+
+	gladefile = g_build_filename (EVOLUTION_GLADEDIR,
+				      "mail-config.glade",
+				      NULL);
+	gui = glade_xml_new (gladefile, "composer_toplevel", NULL);
+	prefs->gui = gui;
+	prefs->sig_script_gui = glade_xml_new (gladefile, "vbox_add_script_signature", NULL);
+	g_free (gladefile);
+
+	/** @HookPoint-EMConfig: Mail Composer Preferences
+	 * @Id: org.gnome.evolution.mail.composerPrefs
+	 * @Type: E_CONFIG_BOOK
+	 * @Class: org.gnome.evolution.mail.config:1.0
+	 * @Target: EMConfigTargetPrefs
+	 *
+	 * The mail composer preferences settings page.
+	 */
+	ec = em_config_new(E_CONFIG_BOOK, "org.gnome.evolution.mail.composerPrefs");
+	l = NULL;
+	for (i = 0; i < G_N_ELEMENTS (emcp_items); i++)
+		l = g_slist_prepend(l, &emcp_items[i]);
+	e_config_add_items((EConfig *)ec, l, NULL, NULL, emcp_free, prefs);
+
+	/* General tab */
+
+	/* Default Behavior */
+	key = "/apps/evolution/mail/composer/send_html";
+	widget = glade_xml_get_widget (gui, "chkSendHTML");
+	if (!gconf_client_key_is_writable (client, key, NULL))
+		gtk_widget_set_sensitive (widget, FALSE);
+	gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
+
+	key = "/apps/evolution/mail/prompts/empty_subject";
+	widget = glade_xml_get_widget (gui, "chkPromptEmptySubject");
+	if (!gconf_client_key_is_writable (client, key, NULL))
+		gtk_widget_set_sensitive (widget, FALSE);
+	gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
+
+	key = "/apps/evolution/mail/prompts/only_bcc";
+	widget = glade_xml_get_widget (gui, "chkPromptBccOnly");
+	if (!gconf_client_key_is_writable (client, key, NULL))
+		gtk_widget_set_sensitive (widget, FALSE);
+	gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
+
+	key = "/apps/evolution/mail/composer/magic_smileys";
+	widget = glade_xml_get_widget (gui, "chkAutoSmileys");
+	if (!gconf_client_key_is_writable (client, key, NULL))
+		gtk_widget_set_sensitive (widget, FALSE);
+	gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
+
+	key = "/apps/evolution/mail/composer/request_receipt";
+	widget = glade_xml_get_widget (gui, "chkRequestReceipt");
+	if (!gconf_client_key_is_writable (client, key, NULL))
+		gtk_widget_set_sensitive (widget, FALSE);
+	gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
+
+	key = "/apps/evolution/mail/composer/reply_start_bottom";
+	widget = glade_xml_get_widget (gui, "chkReplyStartBottom");
+	if (!gconf_client_key_is_writable (client, key, NULL))
+		gtk_widget_set_sensitive (widget, FALSE);
+	gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
+
+	key = "/apps/evolution/mail/composer/outlook_filenames";
+	widget = glade_xml_get_widget (gui, "chkOutlookFilenames");
+	if (!gconf_client_key_is_writable (client, key, NULL))
+		gtk_widget_set_sensitive (widget, FALSE);
+	gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
+
+	key = "/apps/evolution/mail/composer/top_signature";
+	widget = glade_xml_get_widget (gui, "chkTopSignature");
+	if (!gconf_client_key_is_writable (client, key, NULL))
+		gtk_widget_set_sensitive (widget, FALSE);
+	gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
+
+	key = "/apps/evolution/mail/composer/inline_spelling";
+	widget = glade_xml_get_widget (gui, "chkEnableSpellChecking");
+	gconf_bridge_bind_property (bridge, key, G_OBJECT (widget), "active");
+
+	prefs->charset = GTK_OPTION_MENU (
+		glade_xml_get_widget (gui, "omenuCharset1"));
+	buf = gconf_client_get_string (
+		client, "/apps/evolution/mail/composer/charset", NULL);
+	menu = e_charset_picker_new (
+		buf && *buf ? buf : camel_iconv_locale_charset ());
+	gtk_option_menu_set_menu (prefs->charset, GTK_WIDGET (menu));
+	option_menu_connect (
+		prefs, prefs->charset,
+		G_CALLBACK (charset_activate),
+		"/apps/evolution/mail/composer/charset");
+	g_free (buf);
+
+	/* Spell Checking */
+	widget = glade_xml_get_widget (gui, "colorButtonSpellCheckColor");
+	prefs->color = GTK_COLOR_BUTTON (widget);
+	widget = glade_xml_get_widget (gui, "listSpellCheckLanguage");
+	view = GTK_TREE_VIEW (widget);
+	store = gtk_list_store_new (
+		3, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_POINTER);
+	g_signal_connect_swapped (
+		store, "row-changed",
+		G_CALLBACK (spell_language_save), prefs);
+	prefs->language_model = GTK_TREE_MODEL (store);
+	gtk_tree_view_set_model (view, prefs->language_model);
+	renderer = gtk_cell_renderer_toggle_new ();
+	g_signal_connect (
+		renderer, "toggled",
+		G_CALLBACK (spell_language_toggled_cb), prefs);
+	gtk_tree_view_insert_column_with_attributes (
+		view, -1, _("Enabled"),
+		renderer, "active", 0, NULL);
+
+	gtk_tree_view_insert_column_with_attributes (
+		view, -1, _("Language(s)"),
+		gtk_cell_renderer_text_new (),
+		"text", 1, NULL);
+	selection = gtk_tree_view_get_selection (view);
+	gtk_tree_selection_set_mode (selection, GTK_SELECTION_NONE);
+	info_pixmap = glade_xml_get_widget (gui, "pixmapSpellInfo");
+	gtk_image_set_from_stock (
+		GTK_IMAGE (info_pixmap),
+		GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_BUTTON);
+	spell_setup (prefs);
+
+	/* Forwards and Replies */
+	prefs->forward_style = GTK_COMBO_BOX (glade_xml_get_widget (gui, "comboboxForwardStyle"));
+	style = gconf_client_get_int (client, "/apps/evolution/mail/format/forward_style", NULL);
+	gtk_combo_box_set_active (prefs->forward_style, style);
+	g_signal_connect (prefs->forward_style, "changed", G_CALLBACK (style_changed), (gpointer) "/apps/evolution/mail/format/forward_style");
+
+	prefs->reply_style = GTK_COMBO_BOX (glade_xml_get_widget (gui, "comboboxReplyStyle"));
+	style = gconf_client_get_int (client, "/apps/evolution/mail/format/reply_style", NULL);
+	gtk_combo_box_set_active (prefs->reply_style, reply_style_new_order (style, TRUE));
+	g_signal_connect (prefs->reply_style, "changed", G_CALLBACK (style_changed), (gpointer) "/apps/evolution/mail/format/reply_style");
+
+	/* Signatures */
+	dialog = (GtkDialog *) gtk_dialog_new ();
+
+	gtk_widget_realize ((GtkWidget *) dialog);
+	gtk_container_set_border_width ((GtkContainer *)dialog->action_area, 12);
+	gtk_container_set_border_width ((GtkContainer *)dialog->vbox, 0);
+
+	prefs->sig_script_dialog = (GtkWidget *) dialog;
+	gtk_dialog_add_buttons (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+				GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
+	gtk_dialog_set_has_separator (dialog, FALSE);
+	gtk_window_set_title ((GtkWindow *) dialog, _("Add signature script"));
+	g_signal_connect (dialog, "response", G_CALLBACK (sig_add_script_response), prefs);
+	widget = glade_xml_get_widget (prefs->sig_script_gui, "vbox_add_script_signature");
+	gtk_box_pack_start ((GtkBox *) dialog->vbox, widget, TRUE, TRUE, 0);
+
+	key = "/apps/evolution/mail/signatures";
+	sensitive = gconf_client_key_is_writable (client, key, NULL);
+
+	widget = glade_xml_get_widget (gui, "cmdSignatureAdd");
+	gtk_widget_set_sensitive (widget, sensitive);
+	g_signal_connect (
+		widget, "clicked",
+		G_CALLBACK (sig_add_cb), prefs);
+	prefs->sig_add = GTK_BUTTON (widget);
+
+	widget = glade_xml_get_widget (gui, "cmdSignatureAddScript");
+	gtk_widget_set_sensitive (widget, sensitive && !mail_config_scripts_disabled ());
+	g_signal_connect (
+		widget, "clicked",
+		G_CALLBACK (sig_add_script_cb), prefs);
+	prefs->sig_add_script = GTK_BUTTON (widget);
+
+	widget = glade_xml_get_widget (gui, "cmdSignatureEdit");
+	gtk_widget_set_sensitive (widget, sensitive);
+	g_signal_connect (
+		widget, "clicked",
+		G_CALLBACK (sig_edit_cb), prefs);
+	prefs->sig_edit = GTK_BUTTON (widget);
+
+	widget = glade_xml_get_widget (gui, "cmdSignatureDelete");
+	gtk_widget_set_sensitive (widget, sensitive);
+	g_signal_connect (
+		widget, "clicked",
+		G_CALLBACK (sig_delete_cb), prefs);
+	prefs->sig_delete = GTK_BUTTON (widget);
+
+	widget = glade_xml_get_widget (gui, "listSignatures");
+	gtk_widget_set_sensitive (widget, sensitive);
+	prefs->sig_list = GTK_TREE_VIEW (widget);
+	store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
+	gtk_tree_view_set_model (prefs->sig_list, GTK_TREE_MODEL (store));
+	gtk_tree_view_insert_column_with_attributes (
+		prefs->sig_list, -1, _("Signature(s)"),
+		gtk_cell_renderer_text_new (), "text", 0, NULL);
+	selection = gtk_tree_view_get_selection (prefs->sig_list);
+	gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
+	g_signal_connect (
+		selection, "changed",
+		G_CALLBACK (sig_selection_changed), prefs);
+	g_signal_connect (
+		prefs->sig_list, "event",
+		G_CALLBACK (sig_tree_event_cb), prefs);
+
+	sig_fill_list (prefs);
+
+	/* preview GtkHTML widget */
+	widget = glade_xml_get_widget (gui, "scrolled-sig");
+	prefs->sig_preview = (GtkHTML *) gtk_html_new ();
+	g_signal_connect (
+		prefs->sig_preview, "url_requested",
+		G_CALLBACK (url_requested), NULL);
+	gtk_widget_show (GTK_WIDGET (prefs->sig_preview));
+	gtk_container_add (
+		GTK_CONTAINER (widget),
+		GTK_WIDGET (prefs->sig_preview));
+
+	/* get our toplevel widget */
+	target = em_config_target_new_prefs (ec, client);
+	e_config_set_target ((EConfig *)ec, (EConfigTarget *)target);
+	toplevel = e_config_create_widget ((EConfig *)ec);
+	gtk_container_add (GTK_CONTAINER (prefs), toplevel);
+
+	g_signal_connect (
+		prefs->sig_list, "key-press-event",
+		G_CALLBACK (signature_key_press_cb), prefs);
+}
+
+GtkWidget *
+em_composer_prefs_new (void)
+{
+	EMComposerPrefs *prefs;
+
+	prefs = g_object_new (EM_TYPE_COMPOSER_PREFS, NULL);
+	em_composer_prefs_construct (prefs);
+
+	return GTK_WIDGET (prefs);
+}
diff --git a/modules/mail/e-mail-shell-migrate.c b/modules/mail/e-mail-shell-migrate.c
index 4bdb66d..d2614be 100644
--- a/modules/mail/e-mail-shell-migrate.c
+++ b/modules/mail/e-mail-shell-migrate.c
@@ -1945,7 +1945,7 @@ get_nth_sig (gint id)
 
 	if (i == id && e_iterator_is_valid (iter)) {
 		sig = (ESignature *) e_iterator_get (iter);
-		uid = g_strdup (sig->uid);
+		uid = g_strdup (e_signature_get_uid (sig));
 	}
 
 	g_object_unref (iter);
diff --git a/widgets/misc/e-signature-combo-box.c b/widgets/misc/e-signature-combo-box.c
index d447ccc..fe4e474 100644
--- a/widgets/misc/e-signature-combo-box.c
+++ b/widgets/misc/e-signature-combo-box.c
@@ -98,11 +98,7 @@ signature_combo_box_refresh_cb (ESignatureList *signature_list,
 		const gchar *string;
 
 		signature = iter->data;
-
-		if (signature->autogen)
-			string = _("Autogenerated");
-		else
-			string = signature->name;
+		string = e_signature_get_name (signature);
 
 		gtk_list_store_append (store, &tree_iter);
 		gtk_list_store_set (
diff --git a/widgets/misc/e-signature-editor.c b/widgets/misc/e-signature-editor.c
index 53cb349..6992167 100644
--- a/widgets/misc/e-signature-editor.c
+++ b/widgets/misc/e-signature-editor.c
@@ -124,19 +124,23 @@ action_save_and_close_cb (GtkAction *action,
 	html = gtkhtml_editor_get_html_mode (GTKHTML_EDITOR (editor));
 
 	if (editor->priv->signature == NULL) {
+		gchar *new_filename;
+
 		signature = e_signature_new ();
-		signature->name = g_strdup (_("Unnamed"));
-		signature->script = FALSE;
-		signature->html = html;
+		e_signature_set_name (signature, _("Unnamed"));
+		e_signature_set_is_script (signature, FALSE);
+		e_signature_set_is_html (signature, html);
 
 		/* FIXME Pass a GError and deal with it. */
-		signature->filename = e_create_signature_file (NULL);
+		new_filename = e_create_signature_file (NULL);
+		e_signature_set_filename (signature, new_filename);
+		g_free (new_filename);
 	} else {
 		signature = g_object_ref (editor->priv->signature);
-		signature->html = html;
+		e_signature_set_is_html (signature, html);
 	}
 
-	filename = signature->filename;
+	filename = e_signature_get_filename (signature);
 	gtkhtml_editor_save (GTKHTML_EDITOR (editor), filename, html, &error);
 
 	if (error != NULL) {
@@ -167,7 +171,7 @@ action_save_and_close_cb (GtkAction *action,
 	 * XXX ESignatureList misuses const. */
 	same_name = (ESignature *) e_signature_list_find (
 		signature_list, E_SIGNATURE_FIND_NAME, signature_name);
-	if (same_name != NULL && strcmp (signature->uid, same_name->uid) != 0) {
+	if (same_name != NULL && !e_signature_is_equal (signature, same_name)) {
 		e_error_run (
 			GTK_WINDOW (editor),
 			"mail:signature-already-exists",
@@ -177,8 +181,8 @@ action_save_and_close_cb (GtkAction *action,
 		return;
 	}
 
-	g_free (signature->name);
-	signature->name = signature_name;
+	e_signature_set_name (signature, signature_name);
+	g_free (signature_name);
 
 	if (editor->priv->signature != NULL)
 		e_signature_list_change (signature_list, signature);
@@ -428,6 +432,7 @@ e_signature_editor_set_signature (ESignatureEditor *editor,
 {
 	const gchar *filename;
 	const gchar *signature_name;
+	gboolean is_html;
 	gchar *contents;
 	gsize length;
 	GError *error = NULL;
@@ -449,9 +454,10 @@ e_signature_editor_set_signature (ESignatureEditor *editor,
 
 	/* Load signature content. */
 
-	filename = signature->filename;
+	filename = e_signature_get_filename (signature);
+	is_html = e_signature_get_is_html (signature);
 
-	if (signature->html)
+	if (is_html)
 		g_file_get_contents (filename, &contents, &length, &error);
 	else {
 		gchar *data;
@@ -467,7 +473,7 @@ e_signature_editor_set_signature (ESignatureEditor *editor,
 
 	if (error == NULL) {
 		gtkhtml_editor_set_html_mode (
-			GTKHTML_EDITOR (editor), signature->html);
+			GTKHTML_EDITOR (editor), is_html);
 		gtkhtml_editor_set_text_html (
 			GTKHTML_EDITOR (editor), contents, length);
 		g_free (contents);
@@ -478,7 +484,7 @@ e_signature_editor_set_signature (ESignatureEditor *editor,
 
 exit:
 	if (signature != NULL)
-		signature_name = signature->name;
+		signature_name = e_signature_get_name (signature);
 	else
 		signature_name = _("Unnamed");
 
diff --git a/widgets/misc/e-signature-manager.c b/widgets/misc/e-signature-manager.c
index a70bc1d..7e29f75 100644
--- a/widgets/misc/e-signature-manager.c
+++ b/widgets/misc/e-signature-manager.c
@@ -92,9 +92,12 @@ signature_manager_run_script_dialog (ESignatureManager *manager,
 {
 	GtkWidget *dialog;
 	GFile *script_file;
+	const gchar *name;
+	const gchar *filename;
 	const gchar *script_name;
 	gboolean success = FALSE;
 	gpointer parent;
+	gchar *path;
 
 	parent = gtk_widget_get_toplevel (GTK_WIDGET (manager));
 	parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
@@ -102,10 +105,13 @@ signature_manager_run_script_dialog (ESignatureManager *manager,
 	dialog = e_signature_script_dialog_new (parent);
 	gtk_window_set_title (GTK_WINDOW (dialog), title);
 
-	if (signature->filename != NULL && signature->name != NULL) {
+	name = e_signature_get_name (signature);
+	filename = e_signature_get_filename (signature);
 
-		script_file = g_file_new_for_path (signature->filename);
-		script_name = signature->name;
+	if (filename != NULL && name != NULL) {
+
+		script_file = g_file_new_for_path (filename);
+		script_name = name;
 
 		e_signature_script_dialog_set_script_file (
 			E_SIGNATURE_SCRIPT_DIALOG (dialog), script_file);
@@ -123,11 +129,10 @@ signature_manager_run_script_dialog (ESignatureManager *manager,
 	script_name = e_signature_script_dialog_get_script_name (
 		E_SIGNATURE_SCRIPT_DIALOG (dialog));
 
-	g_free (signature->filename);
-	signature->filename = g_file_get_path (script_file);
-
-	g_free (signature->name);
-	signature->name = g_strdup (script_name);
+	path = g_file_get_path (script_file);
+	e_signature_set_name (signature, script_name);
+	e_signature_set_filename (signature, path);
+	g_free (path);
 
 	g_object_unref (script_file);
 
@@ -291,8 +296,8 @@ signature_manager_add_signature_script (ESignatureManager *manager)
 	signature_list = e_signature_manager_get_signature_list (manager);
 
 	signature = e_signature_new ();
-	signature->script = TRUE;
-	signature->html = TRUE;
+	e_signature_set_is_script (signature, TRUE);
+	e_signature_set_is_html (signature, TRUE);
 
 	if (signature_manager_run_script_dialog (manager, signature, title))
 		e_signature_list_add (signature_list, signature);
@@ -327,7 +332,7 @@ signature_manager_edit_signature (ESignatureManager *manager)
 	ESignature *signature;
 	GtkWidget *editor;
 	const gchar *title;
-	gchar *filename;
+	const gchar *filename;
 
 	tree_view = e_signature_manager_get_tree_view (manager);
 	signature = e_signature_tree_view_get_selected (tree_view);
@@ -336,15 +341,12 @@ signature_manager_edit_signature (ESignatureManager *manager)
 	if (signature == NULL)
 		return;
 
-	if (signature->script)
+	if (e_signature_get_is_script (signature))
 		goto script;
 
-	filename = signature->filename;
-	if (filename == NULL || *filename == '\0') {
-		g_free (filename);
-		filename = g_strdup (_("Unnamed"));
-		signature->filename = filename;
-	}
+	filename = e_signature_get_filename (signature);
+	if (filename == NULL || *filename == '\0')
+		e_signature_set_filename (signature, _("Unnamed"));
 
 	editor = e_signature_editor_new ();
 	e_signature_editor_set_signature (
@@ -373,6 +375,8 @@ signature_manager_remove_signature (ESignatureManager *manager)
 	ESignatureTreeView *tree_view;
 	ESignatureList *signature_list;
 	ESignature *signature;
+	const gchar *filename;
+	gboolean is_script;
 
 	tree_view = e_signature_manager_get_tree_view (manager);
 	signature = e_signature_tree_view_get_selected (tree_view);
@@ -381,8 +385,11 @@ signature_manager_remove_signature (ESignatureManager *manager)
 	if (signature == NULL)
 		return;
 
-	if (signature->filename != NULL && !signature->script)
-		g_unlink (signature->filename);
+	filename = e_signature_get_filename (signature);
+	is_script = e_signature_get_is_script (signature);
+
+	if (filename != NULL && !is_script)
+		g_unlink (filename);
 
 	e_signature_list_remove (signature_list, signature);
 	e_signature_list_save (signature_list);
diff --git a/widgets/misc/e-signature-preview.c b/widgets/misc/e-signature-preview.c
index f8e168c..bbef65f 100644
--- a/widgets/misc/e-signature-preview.c
+++ b/widgets/misc/e-signature-preview.c
@@ -155,6 +155,8 @@ signature_preview_refresh (ESignaturePreview *preview)
 {
 	GtkHTML *html;
 	ESignature *signature;
+	const gchar *filename;
+	gboolean is_script;
 	gchar *content = NULL;
 	gsize length;
 
@@ -166,11 +168,14 @@ signature_preview_refresh (ESignaturePreview *preview)
 	if (signature == NULL)
 		goto clear;
 
-	if (signature->script && !preview->priv->allow_scripts)
+	filename = e_signature_get_filename (signature);
+	is_script = e_signature_get_is_script (signature);
+
+	if (is_script && !preview->priv->allow_scripts)
 		goto clear;
 
-	if (signature->script)
-		content = e_run_signature_script (signature->filename);
+	if (is_script)
+		content = e_run_signature_script (filename);
 	else
 		content = e_read_signature_file (signature, FALSE, NULL);
 
@@ -179,7 +184,7 @@ signature_preview_refresh (ESignaturePreview *preview)
 
 	length = strlen (content);
 
-	if (signature->html)
+	if (e_signature_get_is_html (signature))
 		gtk_html_load_from_string (html, content, length);
 	else {
 		GtkHTMLStream *stream;
diff --git a/widgets/misc/e-signature-tree-view.c b/widgets/misc/e-signature-tree-view.c
index b2cc9d6..5c931c8 100644
--- a/widgets/misc/e-signature-tree-view.c
+++ b/widgets/misc/e-signature-tree-view.c
@@ -89,17 +89,20 @@ signature_tree_view_refresh_cb (ESignatureList *signature_list,
 	for (iter = list; iter != NULL; iter = iter->next) {
 		GtkTreeRowReference *reference;
 		GtkTreePath *path;
+		const gchar *name;
 
 		signature = iter->data;
 
 		/* Skip autogenerated signatures. */
-		if (signature->autogen)
+		if (e_signature_get_autogenerated (signature))
 			continue;
 
+		name = e_signature_get_name (signature);
+
 		gtk_list_store_append (store, &tree_iter);
 		gtk_list_store_set (
 			store, &tree_iter,
-			COLUMN_STRING, signature->name,
+			COLUMN_STRING, name,
 			COLUMN_SIGNATURE, signature, -1);
 
 		path = gtk_tree_model_get_path (model, &tree_iter);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]