diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c index d939a7592e..c6437b6d93 100644 --- a/composer/e-msg-composer.c +++ b/composer/e-msg-composer.c @@ -22,6 +22,7 @@ * Ettore Perazzoli (ettore@ximian.com) * Jeffrey Stedfast (fejj@ximian.com) * Miguel de Icaza (miguel@ximian.com) + * Radek Doulik (rodo@ximian.com) * */ @@ -47,9 +48,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -143,6 +146,7 @@ static void handle_multipart_alternative (EMsgComposer *composer, CamelMultipart static void handle_multipart (EMsgComposer *composer, CamelMultipart *multipart, int depth); +static void set_editor_signature (EMsgComposer *composer); @@ -692,7 +696,7 @@ build_message (EMsgComposer *composer) static char * -get_file_content (EMsgComposer *composer, const char *file_name, gboolean want_html, guint flags) +get_file_content (EMsgComposer *composer, const char *file_name, gboolean want_html, guint flags, gboolean warn) { CamelStreamFilter *filtered_stream; CamelStreamMem *memstream; @@ -706,11 +710,13 @@ get_file_content (EMsgComposer *composer, const char *file_name, gboolean want_h fd = open (file_name, O_RDONLY | O_CREAT, 0644); if (fd == -1) { char *msg; - - msg = g_strdup_printf (_("Error while reading file %s:\n%s"), - file_name, g_strerror (errno)); - gnome_error_dialog (msg); - g_free (msg); + + if (warn) { + msg = g_strdup_printf (_("Error while reading file %s:\n%s"), + file_name, g_strerror (errno)); + gnome_error_dialog (msg); + g_free (msg); + } return g_strdup (""); } @@ -751,7 +757,7 @@ e_msg_composer_get_sig_file_content (const char *sigfile, gboolean in_html) return NULL; } - return get_file_content (NULL, sigfile, !in_html, 0); + return get_file_content (NULL, sigfile, !in_html, 0, FALSE); } static void @@ -773,10 +779,11 @@ prepare_engine (EMsgComposer *composer) composer->editor_listener = BONOBO_OBJECT (listener_new (composer)); if (composer->editor_listener != NULL) GNOME_GtkHTML_Editor_Engine__set_listener (composer->editor_engine, - (GNOME_GtkHTML_Editor_Listener) - bonobo_object_dup_ref - (bonobo_object_corba_objref (composer->editor_listener), &ev), - &ev); + (GNOME_GtkHTML_Editor_Listener) + bonobo_object_dup_ref + (bonobo_object_corba_objref (composer->editor_listener), + &ev), + &ev); if ((ev._major != CORBA_NO_EXCEPTION) || (composer->editor_listener == NULL)) { CORBA_Environment err_ev; @@ -803,26 +810,47 @@ static gchar * get_signature_html (EMsgComposer *composer) { gboolean format_html = FALSE; - char *text, *html = NULL, *sig_file = NULL; + char *text, *html = NULL, *sig_file = NULL, *script = NULL; + static gboolean random_initialized = FALSE; - if (E_MSG_COMPOSER_HDRS (composer->hdrs)->account->id) { - MailConfigIdentity *id; - - id = E_MSG_COMPOSER_HDRS (composer->hdrs)->account->id; - if (composer->send_html) { - if (id->has_html_signature) { - sig_file = id->html_signature; - format_html = TRUE; - } else - sig_file = id->signature; - } else - sig_file = id->signature; + if (composer->signature) { + sig_file = composer->signature->filename; + format_html = composer->signature->html; + script = composer->signature->script; + } else if (composer->random_signature) { + GList *l; + gint pos; + + if (!random_initialized) { + printf ("initialize random generator\n"); + srand (time (NULL)); + random_initialized = TRUE; + } + pos = (int) (((gdouble) mail_config_get_signatures_random ())*rand()/(RAND_MAX+1.0)); + printf ("using %d sig\n", pos); + + for (l = mail_config_get_signature_list (); l; l = l->next) { + MailConfigSignature *sig = (MailConfigSignature *) l->data; + + if (sig->random) { + if (pos == 0) { + printf ("using %s\n", sig->name); + sig_file = sig->filename; + script = sig->script; + format_html = sig->html; + break; + } + pos --; + } + } } - if (!sig_file) return NULL; - + printf ("sig file: %s\n", sig_file); + + mail_config_signature_run_script (script); text = e_msg_composer_get_sig_file_content (sig_file, format_html); + /* printf ("text: %s\n", text); */ if (text) { /* 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, @@ -1483,7 +1511,7 @@ menu_file_insert_file_cb (BonoboUIComponent *uic, if (file_name == NULL) return; - html = get_file_content (composer, file_name, TRUE, E_TEXT_TO_HTML_PRE); + html = get_file_content (composer, file_name, TRUE, E_TEXT_TO_HTML_PRE, TRUE); if (html == NULL) return; @@ -1675,6 +1703,151 @@ static EPixmap pixcache [] = { E_PIXMAP_END }; +static void +signature_regenerate_cb (BonoboUIComponent *uic, gpointer user_data, const char *path) +{ + printf ("signature_regenerate_cb: %s\n", path); + + e_msg_composer_show_sig_file (E_MSG_COMPOSER (user_data)); +} + +static void +signature_cb (BonoboUIComponent *uic, const char *path, Bonobo_UIComponent_EventType type, + const char *state, gpointer user_data) +{ + EMsgComposer *composer = (EMsgComposer *) user_data; + + printf ("signature_cb: %s (%s)\n", path, state); + + if (state && *state == '1') { + if (path && !strncmp (path, "Signature", 9)) { + MailConfigSignature *old_sig; + gboolean old_random; + + old_sig = composer->signature; + old_random = composer->random_signature; + + printf ("I'm going to set signature (%d)\n", atoi (path + 9)); + if (path [9] == 'N') { + composer->signature = NULL; + composer->random_signature = FALSE; + } else if (path [9] == 'R') { + composer->signature = NULL; + composer->random_signature = TRUE; + } else { + composer->signature = g_list_nth_data (mail_config_get_signature_list (), atoi (path + 9)); + composer->random_signature = FALSE; + } + if (old_sig != composer->signature || old_random != composer->random_signature) + e_msg_composer_show_sig_file (composer); + } + } + + printf ("signature_cb end\n"); +} + +static void setup_signatures_menu (EMsgComposer *composer); + +static void +remove_signature_list (EMsgComposer *composer) +{ + gchar path [64]; + gint len = g_list_length (mail_config_get_signature_list ()); + + bonobo_ui_component_rm (composer->uic, "/menu/Edit/EditMisc/EditSignaturesSubmenu/SeparatorList", NULL); + bonobo_ui_component_rm (composer->uic, "/menu/Edit/EditMisc/EditSignaturesSubmenu/SeparatorRegenerate", NULL); + bonobo_ui_component_rm (composer->uic, "/menu/Edit/EditMisc/EditSignaturesSubmenu/SignatureRegenerate", NULL); + for (; len; len --) { + g_snprintf (path, 64, "/menu/Edit/EditMisc/EditSignaturesSubmenu/Signature%d", len - 1); + bonobo_ui_component_rm (composer->uic, path, NULL); + } +} + +static void +sig_event_client (MailConfigSigEvent event, MailConfigSignature *sig, EMsgComposer *composer) +{ + gchar *path; + + bonobo_ui_component_freeze (composer->uic, NULL); + switch (event) { + case MAIL_CONFIG_SIG_EVENT_DELETED: + if (sig == composer->signature) + composer->signature = NULL; + path = g_strdup_printf ("/menu/Edit/EditMisc/EditSignaturesSubmenu/Signature%d", + g_list_length (mail_config_get_signature_list ())); + bonobo_ui_component_rm (composer->uic, path, NULL); + g_free (path); + setup_signatures_menu (composer); + break; + case MAIL_CONFIG_SIG_EVENT_RANDOM_OFF: + composer->random_signature = FALSE; + bonobo_ui_component_rm (composer->uic, "/menu/Edit/EditMisc/EditSignaturesSubmenu/SignatureRandom", NULL); + bonobo_ui_component_rm (composer->uic, "/menu/Edit/EditMisc/EditSignaturesSubmenu/SeparatorRandom", NULL); + setup_signatures_menu (composer); + break; + case MAIL_CONFIG_SIG_EVENT_RANDOM_ON: + remove_signature_list (composer); + setup_signatures_menu (composer); + break; + case MAIL_CONFIG_SIG_EVENT_ADDED: + case MAIL_CONFIG_SIG_EVENT_NAME_CHANGED: + setup_signatures_menu (composer); + } + bonobo_ui_component_thaw (composer->uic, NULL); +} + +static void +setup_signatures_menu (EMsgComposer *composer) +{ + GList *l, *list; + GString *str; + gchar *line; + gint i, len = 0; + + str = g_string_new ("\n" + "\n"); + if (mail_config_get_signatures_random ()) { + g_string_append (str, + "\n" + "\n"); + } + + list = mail_config_get_signature_list (); + if (list) { + + g_string_append (str, ""); + + for (l = list; l; len ++, l = l->next) { + line = g_strdup_printf ("\n", + len, ((MailConfigSignature *)l->data)->name, len); + g_string_append (str, line); + g_free (line); + } + } + + g_string_append (str, + "\n" + ""); + g_string_append (str, "\n"); + + bonobo_ui_component_set_translate (composer->uic, "/menu/Edit/EditMisc/", str->str, NULL); + bonobo_ui_component_set (composer->uic, "/menu/Edit/EditMisc/", "", NULL); + + bonobo_ui_component_add_listener (composer->uic, "SignatureNone", signature_cb, composer); + bonobo_ui_component_add_listener (composer->uic, "SignatureRandom", signature_cb, composer); + bonobo_ui_component_add_verb (composer->uic, "SignatureRegenerate", signature_regenerate_cb, composer); + + for (i = 0; i < len; i ++) { + g_string_sprintf (str, "Signature%d", i + 1); + bonobo_ui_component_add_listener (composer->uic, str->str, signature_cb, composer); + } + g_string_free (str, TRUE); +} + static void setup_ui (EMsgComposer *composer) { @@ -1826,6 +1999,9 @@ setup_ui (EMsgComposer *composer) bonobo_ui_component_add_listener ( composer->uic, "ViewAttach", menu_view_attachments_activate_cb, composer); + + setup_signatures_menu (composer); + mail_config_signature_register_client ((MailConfigSignatureClient) sig_event_client, composer); bonobo_ui_component_thaw (composer->uic, NULL); } @@ -2003,7 +2179,8 @@ from_changed_cb (EMsgComposerHdrs *hdrs, void *data) update_auto_recipients (hdrs, UPDATE_AUTO_CC, NULL); update_auto_recipients (hdrs, UPDATE_AUTO_BCC, NULL); } - + + set_editor_signature (composer); e_msg_composer_show_sig_file (composer); } @@ -2030,6 +2207,8 @@ destroy (GtkObject *object) composer = E_MSG_COMPOSER (object); + mail_config_signature_register_client ((MailConfigSignatureClient) sig_event_client, composer); + CORBA_exception_init (&ev); if (composer->config_db) { @@ -2572,6 +2751,38 @@ create_composer (void) return composer; } +static void +set_editor_signature (EMsgComposer *composer) +{ + printf ("set_editor_signature\n"); + if (E_MSG_COMPOSER_HDRS (composer->hdrs)->account->id) { + MailConfigIdentity *id; + gchar *verb, *name; + + id = E_MSG_COMPOSER_HDRS (composer->hdrs)->account->id; + + composer->random_signature = composer->send_html ? id->html_random : id->text_random; + if (composer->random_signature) + composer->signature = NULL; + else + composer->signature = composer->send_html ? id->html_signature : id->text_signature; + + if (composer->random_signature) { + verb = g_strdup ("/commands/SignatureRandom"); + name = g_strdup ("SignatureRandom"); + } else if (composer->signature == NULL) { + verb = g_strdup ("/commands/SignatureNone"); + name = g_strdup ("SignatureNone"); + } else { + verb = g_strdup_printf ("/commands/Signature%d", composer->signature->id); + name = g_strdup_printf ("Signature%d", composer->signature->id); + } + bonobo_ui_component_set_prop (composer->uic, verb, "state", "1", NULL); + g_free (verb); + } + printf ("set_editor_signature end\n"); +} + /** * e_msg_composer_new: * @@ -2588,6 +2799,7 @@ e_msg_composer_new (void) if (new) { e_msg_composer_set_send_html (new, mail_config_get_send_html ()); set_editor_text (new, ""); + set_editor_signature (new); } return new; @@ -2969,8 +3181,10 @@ e_msg_composer_new_with_message (CamelMimeMessage *message) /* We wait until now to set the body text because we need to ensure that * the attachment bar has all the attachments, before we request them. - */ + */ e_msg_composer_flush_pending_body (new, TRUE); + + set_editor_signature (new); return new; } @@ -3474,6 +3688,7 @@ e_msg_composer_show_sig_file (EMsgComposer *composer) g_return_if_fail (composer != NULL); g_return_if_fail (E_IS_MSG_COMPOSER (composer)); + printf ("e_msg_composer_show_sig_file\n"); /* printf ("set sig '%s' '%s'\n", sig_file, composer->sig_file); */ composer->in_signature_insert = TRUE; @@ -3497,11 +3712,14 @@ e_msg_composer_show_sig_file (EMsgComposer *composer) GNOME_GtkHTML_Editor_Engine_insertHTML (composer->editor_engine, html, &ev); g_free (html); } + GNOME_GtkHTML_Editor_Engine_undoEnd (composer->editor_engine, &ev); GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "cursor-position-restore", &ev); GNOME_GtkHTML_Editor_Engine_thaw (composer->editor_engine, &ev); CORBA_exception_free (&ev); composer->in_signature_insert = FALSE; + + printf ("e_msg_composer_show_sig_file end\n"); } /** @@ -3538,6 +3756,7 @@ e_msg_composer_set_send_html (EMsgComposer *composer, composer->send_html, NULL); set_config (composer, "FormatHTML", composer->send_html); + set_editor_signature (composer); e_msg_composer_show_sig_file (composer); GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "unblock-redraw", &ev); CORBA_exception_free (&ev); diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h index 100760f87e..921dfc2ee1 100644 --- a/composer/e-msg-composer.h +++ b/composer/e-msg-composer.h @@ -99,6 +99,9 @@ struct _EMsgComposer { gboolean enable_autosave : 1; CamelMimeMessage *redirect; + + MailConfigSignature *signature; + gboolean random_signature; }; struct _EMsgComposerClass { diff --git a/mail/Mail.idl b/mail/Mail.idl index f68889e0c2..239decd479 100644 --- a/mail/Mail.idl +++ b/mail/Mail.idl @@ -45,9 +45,6 @@ module Evolution { string name; string address; string organization; - string signature; - string html_signature; - boolean has_html_signature; }; struct Service { diff --git a/mail/Makefile.am b/mail/Makefile.am index cd4b6f29d2..2a2a784d07 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -94,6 +94,8 @@ evolution_mail_SOURCES = \ mail-send-recv.h \ mail-session.c \ mail-session.h \ + mail-signature-editor.c \ + mail-signature-editor.h \ mail-stream-gtkhtml.c \ mail-stream-gtkhtml.h \ mail-tools.c \ diff --git a/mail/mail-account-editor.c b/mail/mail-account-editor.c index 166c3f1df9..552e266398 100644 --- a/mail/mail-account-editor.c +++ b/mail/mail-account-editor.c @@ -146,11 +146,11 @@ cancel_clicked (GtkWidget *widget, gpointer data) } static void -construct (MailAccountEditor *editor, MailConfigAccount *account) +construct (MailAccountEditor *editor, MailConfigAccount *account, MailAccountsDialog *dialog) { MailConfigService *source = account->source; - editor->gui = mail_account_gui_new (account); + editor->gui = mail_account_gui_new (account, dialog); /* get our toplevel widget and reparent it */ editor->notebook = GTK_NOTEBOOK (glade_xml_get_widget (editor->gui->xml, "account_editor_notebook")); @@ -182,13 +182,13 @@ construct (MailAccountEditor *editor, MailConfigAccount *account) } MailAccountEditor * -mail_account_editor_new (MailConfigAccount *account, GtkWindow *parent) +mail_account_editor_new (MailConfigAccount *account, GtkWindow *parent, MailAccountsDialog *dialog) { MailAccountEditor *new; new = (MailAccountEditor *) gtk_type_new (mail_account_editor_get_type ()); gnome_dialog_set_parent (GNOME_DIALOG (new), parent); - construct (new, account); + construct (new, account, dialog); return new; } diff --git a/mail/mail-account-editor.h b/mail/mail-account-editor.h index 22e4158b95..d4225e324c 100644 --- a/mail/mail-account-editor.h +++ b/mail/mail-account-editor.h @@ -32,6 +32,7 @@ extern "C" { #include #include #include "mail-account-gui.h" +#include "mail-accounts.h" #define MAIL_ACCOUNT_EDITOR_TYPE (mail_account_editor_get_type ()) #define MAIL_ACCOUNT_EDITOR(o) (GTK_CHECK_CAST ((o), MAIL_ACCOUNT_EDITOR_TYPE, MailAccountEditor)) @@ -57,7 +58,7 @@ typedef struct { GtkType mail_account_editor_get_type (void); -MailAccountEditor *mail_account_editor_new (MailConfigAccount *account, GtkWindow *parent); +MailAccountEditor *mail_account_editor_new (MailConfigAccount *account, GtkWindow *parent, MailAccountsDialog *dialog); #ifdef __cplusplus } diff --git a/mail/mail-account-gui.c b/mail/mail-account-gui.c index f6ca76846a..981a1b98e9 100644 --- a/mail/mail-account-gui.c +++ b/mail/mail-account-gui.c @@ -29,8 +29,6 @@ #include #include -#include -#include #include #include @@ -38,7 +36,7 @@ #include "mail-account-gui.h" #include "mail-session.h" #include "mail-send-recv.h" -#include "e-msg-composer.h" +#include "mail-signature-editor.h" #define d(x) @@ -961,303 +959,6 @@ provider_compare (const CamelProvider *p1, const CamelProvider *p2) } } -/* - * Signature editor - * - */ - -struct _ESignatureEditor { - MailAccountGui *gui; - GtkWidget *win; - GtkWidget *control; - - gchar *filename; - gboolean html; - gboolean has_changed; -}; -typedef struct _ESignatureEditor ESignatureEditor; - -#define E_SIGNATURE_EDITOR(o) ((ESignatureEditor *) o) - -#define DEFAULT_WIDTH 600 -#define DEFAULT_HEIGHT 500 - -enum { REPLY_YES = 0, REPLY_NO, REPLY_CANCEL }; - -static void -destroy_editor (ESignatureEditor *editor) -{ - gtk_widget_destroy (editor->win); - g_free (editor->filename); - g_free (editor); -} - -static void -menu_file_save_error (BonoboUIComponent *uic, CORBA_Environment *ev) { - e_notice (GTK_WINDOW (uic), GNOME_MESSAGE_BOX_ERROR, - _("Could not save signature file.")); - - g_warning ("Exception while saving signature (%s)", - bonobo_exception_get_text (ev)); -} - -static void -menu_file_save_cb (BonoboUIComponent *uic, - void *data, - const char *path) -{ - ESignatureEditor *editor; - Bonobo_PersistFile pfile_iface; - CORBA_Environment ev; - - editor = E_SIGNATURE_EDITOR (data); - if (editor->html) { - CORBA_exception_init (&ev); - - pfile_iface = bonobo_object_client_query_interface (bonobo_widget_get_server (BONOBO_WIDGET (editor->control)), - "IDL:Bonobo/PersistFile:1.0", NULL); - Bonobo_PersistFile_save (pfile_iface, editor->filename, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - menu_file_save_error (uic, &ev); - - CORBA_exception_free (&ev); - } else { - BonoboStream *stream; - CORBA_Environment ev; - Bonobo_PersistStream pstream_iface; - - CORBA_exception_init (&ev); - - stream = bonobo_stream_open (BONOBO_IO_DRIVER_FS, editor->filename, - Bonobo_Storage_WRITE | Bonobo_Storage_CREATE, 0); - - pstream_iface = bonobo_object_client_query_interface - (bonobo_widget_get_server (BONOBO_WIDGET (editor->control)), - "IDL:Bonobo/PersistStream:1.0", NULL); - - Bonobo_PersistStream_save (pstream_iface, - (Bonobo_Stream) bonobo_object_corba_objref (BONOBO_OBJECT (stream)), - "text/plain", &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - menu_file_save_error (uic, &ev); - - CORBA_exception_free (&ev); - bonobo_object_unref (BONOBO_OBJECT (stream)); - } -} - -static void -exit_dialog_cb (int reply, ESignatureEditor *editor) -{ - switch (reply) { - case REPLY_YES: - menu_file_save_cb (NULL, editor, NULL); - destroy_editor (editor); - break; - case REPLY_NO: - destroy_editor (editor); - break; - case REPLY_CANCEL: - default: - } -} - -static void -do_exit (ESignatureEditor *editor) -{ - if (editor->has_changed) { - GtkWidget *dialog; - GtkWidget *label; - gint button; - - dialog = gnome_dialog_new (_("Save signature"), - GNOME_STOCK_BUTTON_YES, /* Save */ - GNOME_STOCK_BUTTON_NO, /* Don't save */ - GNOME_STOCK_BUTTON_CANCEL, /* Cancel */ - NULL); - - label = gtk_label_new (_("This signature has been changed, but hasn't been saved.\n" - "\nDo you wish to save your changes?")); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label, TRUE, TRUE, 0); - gtk_widget_show (label); - gnome_dialog_set_parent (GNOME_DIALOG (dialog), GTK_WINDOW (editor->win)); - gnome_dialog_set_default (GNOME_DIALOG (dialog), 0); - button = gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); - - exit_dialog_cb (button, editor); - } else - destroy_editor (editor); -} - -static int -delete_event_cb (GtkWidget *w, GdkEvent *event, ESignatureEditor *editor) -{ - do_exit (editor); - - return FALSE; -} - -static void -menu_file_close_cb (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - ESignatureEditor *editor; - - editor = E_SIGNATURE_EDITOR (data); - do_exit (editor); -} - -static void -menu_file_save_close_cb (BonoboUIComponent *uic, gpointer data, const gchar *path) -{ - ESignatureEditor *editor; - - editor = E_SIGNATURE_EDITOR (data); - - menu_file_save_cb (uic, editor, path); - destroy_editor (editor); -} - -static BonoboUIVerb verbs [] = { - - BONOBO_UI_VERB ("FileSave", menu_file_save_cb), - BONOBO_UI_VERB ("FileClose", menu_file_close_cb), - BONOBO_UI_VERB ("FileSaveClose", menu_file_save_close_cb), - - BONOBO_UI_VERB_END -}; - -static void -load_signature (ESignatureEditor *editor) -{ - CORBA_Environment ev; - - if (editor->html) { - Bonobo_PersistFile pfile_iface; - - pfile_iface = bonobo_object_client_query_interface (bonobo_widget_get_server (BONOBO_WIDGET (editor->control)), - "IDL:Bonobo/PersistFile:1.0", NULL); - CORBA_exception_init (&ev); - Bonobo_PersistFile_load (pfile_iface, editor->filename, &ev); - CORBA_exception_free (&ev); - } else { - Bonobo_PersistStream pstream_iface; - BonoboStream *stream; - gchar *data, *html; - - data = e_msg_composer_get_sig_file_content (editor->filename, FALSE); - html = g_strdup_printf ("
\n%s", data);
-		g_free (data);
-		
-		pstream_iface = bonobo_object_client_query_interface
-			(bonobo_widget_get_server (BONOBO_WIDGET (editor->control)),
-			 "IDL:Bonobo/PersistStream:1.0", NULL);
-		CORBA_exception_init (&ev);
-		stream = bonobo_stream_mem_create (html, strlen (html), TRUE, FALSE);
-		
-		if (stream == NULL) {
-			g_warning ("Couldn't create memory stream\n");
-		} else {
-			BonoboObject *stream_object;
-			Bonobo_Stream corba_stream;
-			
-			stream_object = BONOBO_OBJECT (stream);
-			corba_stream = bonobo_object_corba_objref (stream_object);
-			Bonobo_PersistStream_load (pstream_iface, corba_stream,
-						   "text/html", &ev);
-		}
-		
-		Bonobo_Unknown_unref (pstream_iface, &ev);
-		CORBA_Object_release (pstream_iface, &ev);
-		CORBA_exception_free (&ev);
-		bonobo_object_unref (BONOBO_OBJECT (stream));
-		
-		g_free (html);
-	}
-}
-
-static void
-launch_signature_editor (MailAccountGui *gui, const gchar *filename, gboolean html)
-{
-	ESignatureEditor *editor;
-	BonoboUIComponent *component;
-	BonoboUIContainer *container;
-	gchar *title;
-	
-	if (!filename || !*filename)
-		return;
-	
-	editor = g_new0 (ESignatureEditor, 1);
-	
-	editor->html     = html;
-	editor->filename = g_strdup (filename);
-	editor->has_changed = TRUE;
-
-	title       = g_strdup_printf ("Edit %ssignature (%s)", html ? "HTML " : "", filename);
-	editor->win = bonobo_window_new ("e-sig-editor", title);
-	editor->gui = gui;
-	gtk_window_set_default_size (GTK_WINDOW (editor->win), DEFAULT_WIDTH, DEFAULT_HEIGHT);
-	gtk_window_set_policy (GTK_WINDOW (editor->win), FALSE, TRUE, FALSE);
-	gtk_window_set_modal (GTK_WINDOW (editor->win), TRUE);
-	g_free (title);
-	
-	container = bonobo_ui_container_new ();
-	bonobo_ui_container_set_win (container, BONOBO_WINDOW (editor->win));
-	
-	component = bonobo_ui_component_new_default ();
-	bonobo_ui_component_set_container (component, bonobo_object_corba_objref (BONOBO_OBJECT (container)));
-	bonobo_ui_component_add_verb_list_with_data (component, verbs, editor);
-	bonobo_ui_util_set_ui (component, EVOLUTION_DATADIR, "evolution-signature-editor.xml", "evolution-signature-editor");
-	
-	editor->control = bonobo_widget_new_control ("OAFIID:GNOME_GtkHTML_Editor",
-						     bonobo_ui_component_get_container (component));
-	
-	if (editor->control == NULL) {
-		g_warning ("Cannot get 'OAFIID:GNOME_GtkHTML_Editor'.");
-		
-		destroy_editor (editor);
-		return;
-	}
-	
-	load_signature (editor);
-
-	gtk_signal_connect (GTK_OBJECT (editor->win), "delete_event",
-			    GTK_SIGNAL_FUNC (delete_event_cb), editor);
-
-	bonobo_window_set_contents (BONOBO_WINDOW (editor->win), editor->control);
-	bonobo_widget_set_property (BONOBO_WIDGET (editor->control), "FormatHTML", html, NULL);
-	gtk_widget_show (GTK_WIDGET (editor->win));
-	gtk_widget_show (GTK_WIDGET (editor->control));
-	gtk_widget_grab_focus (editor->control);
-}
-
-static void
-edit_signature (GtkWidget *w, MailAccountGui *gui)
-{
-	launch_signature_editor (gui, gtk_entry_get_text (GTK_ENTRY (gnome_file_entry_gtk_entry (gui->signature))), FALSE);
-}
-
-static void
-edit_html_signature (GtkWidget *w, MailAccountGui *gui)
-{
-	launch_signature_editor (gui, gtk_entry_get_text (GTK_ENTRY (gnome_file_entry_gtk_entry (gui->html_signature))), TRUE);
-}
-
-static void
-signature_changed (GtkWidget *entry, MailAccountGui *gui)
-{
-	gtk_widget_set_sensitive (GTK_WIDGET (gui->edit_signature),
-				  *gtk_entry_get_text (GTK_ENTRY (gnome_file_entry_gtk_entry (gui->signature))) != 0);
-}
-
-static void
-html_signature_changed (GtkWidget *entry, MailAccountGui *gui)
-{
-	gtk_widget_set_sensitive (GTK_WIDGET (gui->edit_html_signature),
-				  *gtk_entry_get_text (GTK_ENTRY (gnome_file_entry_gtk_entry (gui->html_signature))) != 0);
-}
-
 static void
 ssl_option_activate (GtkWidget *widget, gpointer user_data)
 {
@@ -1290,13 +991,377 @@ construct_ssl_menu (MailAccountGuiService *service)
 	gtk_signal_emit_by_name (GTK_OBJECT (item), "activate", service);
 }
 
+  static void
+clear_menu (GtkWidget *menu)
+{
+	while (GTK_MENU_SHELL (menu)->children)
+		gtk_container_remove (GTK_CONTAINER (menu), GTK_MENU_SHELL (menu)->children->data);
+}
+
+static inline gint
+sig_get_index (MailConfigSignature *sig)
+{
+	return sig->id + (mail_config_get_signatures_random () ? 2 : 1);
+}
+
+static gint
+sig_get_gui_index (MailAccountGui *gui, gboolean text)
+{
+	MailConfigSignature *sig = text ? gui->text_signature : gui->html_signature;
+	gboolean random = text ? gui->text_random : gui->html_random;
+
+	if (random)
+		return 1;
+	else if (!sig)
+		return 0;
+	else
+		return sig_get_index (sig);
+}
+
+static void
+sig_fill_options (MailAccountGui *gui)
+{
+	GtkWidget *menu_text, *menu_html;
+	GtkWidget *mi;
+	GList *l;
+	MailConfigSignature *sig;
+
+	menu_text = gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_text));
+	menu_html = gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_html));
+
+	clear_menu (menu_text);
+	clear_menu (menu_html);
+
+	gtk_menu_append (GTK_MENU (menu_text), gtk_menu_item_new_with_label (_("None")));
+	gtk_menu_append (GTK_MENU (menu_html), gtk_menu_item_new_with_label (_("None")));
+
+	if (mail_config_get_signatures_random ()) {
+		gtk_menu_append (GTK_MENU (menu_text), gtk_menu_item_new_with_label (_("Random")));
+		gtk_menu_append (GTK_MENU (menu_html), gtk_menu_item_new_with_label (_("Random")));
+	}
+
+	for (l = mail_config_get_signature_list (); l; l = l->next) {
+		sig = l->data;
+		mi = gtk_menu_item_new_with_label (sig->name);
+		gtk_object_set_data (GTK_OBJECT (mi), "sig", sig);
+		gtk_menu_append (GTK_MENU (menu_text), mi);
+
+		mi = gtk_menu_item_new_with_label (sig->name);
+		gtk_object_set_data (GTK_OBJECT (mi), "sig", sig);
+		gtk_menu_append (GTK_MENU (menu_html), mi);
+	}
+}
+
+static void
+sig_select_text_sig (MailAccountGui *gui)
+{
+	gtk_option_menu_set_history (GTK_OPTION_MENU (gui->sig_option_text), sig_get_gui_index (gui, TRUE));
+}
+
+static void
+sig_select_html_sig (MailAccountGui *gui)
+{
+	gtk_option_menu_set_history (GTK_OPTION_MENU (gui->sig_option_html), sig_get_gui_index (gui, FALSE));
+}
+
+static void
+sig_changed_text (GtkWidget *w, MailAccountGui *gui)
+{
+	GtkWidget *active;
+	gint index;
+
+	active = gtk_menu_get_active (GTK_MENU (w));
+	index = g_list_index (GTK_MENU_SHELL (w)->children, active);
+
+	gui->text_signature = (MailConfigSignature *) gtk_object_get_data (GTK_OBJECT (active), "sig");
+	gui->text_random = index == 1;
+
+	gtk_widget_set_sensitive (GTK_WIDGET (gui->sig_edit_text), gui->text_signature != NULL);
+}
+
+static void
+sig_changed_html (GtkWidget *w, MailAccountGui *gui)
+{
+	GtkWidget *active;
+	gint index;
+
+	active = gtk_menu_get_active (GTK_MENU (w));
+	index = g_list_index (GTK_MENU_SHELL (w)->children, active);
+
+	gui->html_signature = (MailConfigSignature *) gtk_object_get_data (GTK_OBJECT (active), "sig");
+	gui->html_random = index == 1;
+
+	gtk_widget_set_sensitive (GTK_WIDGET (gui->sig_edit_html), gui->html_signature != NULL);
+}
+
+static void
+sig_edit_text (GtkWidget *w, MailAccountGui *gui)
+{
+	MailConfigSignature *sig = gui->text_signature;
+
+	if (!sig)
+		return;
+
+	if (sig->filename && *sig->filename)
+		mail_signature_editor (sig->filename, sig->html);
+	else
+		e_notice (NULL, GNOME_MESSAGE_BOX_ERROR,
+			  _("Please specify signature filename\nin Andvanced section of signature settings."));
+}
+
+static void
+sig_edit_html (GtkWidget *w, MailAccountGui *gui)
+{
+	MailConfigSignature *sig = gui->html_signature;
+
+	if (!sig)
+		return;
+
+	if (sig->filename && *sig->filename)
+		mail_signature_editor (sig->filename, sig->html);
+	else
+		e_notice (NULL, GNOME_MESSAGE_BOX_ERROR,
+			  _("Please specify signature filename\nin Andvanced section of signature settings."));
+}
+
+static void
+sig_switch_to_list (GtkWidget *w, MailAccountGui *gui)
+{
+	gtk_window_set_transient_for (GTK_WINDOW (gtk_widget_get_toplevel (w)), NULL);
+	gdk_window_raise (GTK_WIDGET (gui->dialog)->window);
+	gtk_notebook_set_page (GTK_NOTEBOOK (glade_xml_get_widget (gui->dialog->gui, "notebook")), 3);
+}
+
+static void
+sig_set_and_write (MailAccountGui *gui)
+{
+	gui->account->id->text_signature = gui->text_signature;
+	gui->account->id->text_random = gui->text_random;
+	gui->account->id->html_signature = gui->html_signature;
+	gui->account->id->html_random = gui->html_random;
+
+	mail_config_write_account_sig (gui->account, -1);
+}
+
+static void
+sig_new_text (GtkWidget *w, MailAccountGui *gui)
+{
+	if (!gui->dialog)
+		return;
+
+	sig_switch_to_list (w, gui);
+
+	gui->text_signature = mail_accounts_dialog_new_signature (gui->dialog, FALSE);
+	gui->text_random = FALSE;
+	
+	gtk_option_menu_set_history (GTK_OPTION_MENU (gui->sig_option_text), sig_get_index (gui->text_signature));
+
+	sig_set_and_write (gui);
+}
+
+static void
+sig_new_html (GtkWidget *w, MailAccountGui *gui)
+{
+	if (!gui->dialog)
+		return;
+
+	sig_switch_to_list (w, gui);
+
+	gui->html_signature = mail_accounts_dialog_new_signature (gui->dialog, TRUE);
+	gui->html_random = FALSE;
+	
+	gtk_option_menu_set_history (GTK_OPTION_MENU (gui->sig_option_html), sig_get_index (gui->html_signature));
+
+	sig_set_and_write (gui);
+}
+
+static void
+setup_signatures (MailAccountGui *gui)
+{
+	gui->text_signature = gui->account->id->text_signature;
+	gui->text_random = gui->account->id->text_random;
+	gui->html_signature = gui->account->id->html_signature;
+	gui->html_random = gui->account->id->html_random;
+
+	sig_select_text_sig (gui);
+	sig_select_html_sig (gui);
+
+	gtk_widget_set_sensitive (GTK_WIDGET (gui->sig_edit_text), gui->text_signature != NULL);
+	gtk_widget_set_sensitive (GTK_WIDGET (gui->sig_edit_html), gui->html_signature != NULL);
+}
+
+static void
+sig_event_client (MailConfigSigEvent event, MailConfigSignature *sig, MailAccountGui *gui)
+{
+	switch (event) {
+	case MAIL_CONFIG_SIG_EVENT_ADDED: {
+
+		GtkWidget *menu;
+		GtkWidget *mi;
+
+		printf ("accounts ADDED\n");
+		mi = gtk_menu_item_new_with_label (sig->name);
+		gtk_object_set_data (GTK_OBJECT (mi), "sig", sig);
+		gtk_widget_show (mi);
+		menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_text));
+		gtk_menu_append (GTK_MENU (menu), mi);
+
+		mi = gtk_menu_item_new_with_label (sig->name);
+		gtk_object_set_data (GTK_OBJECT (mi), "sig", sig);
+		gtk_widget_show (mi);
+		menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_html));
+		gtk_menu_append (GTK_MENU (GTK_MENU (menu)), mi);
+
+		break;
+	}
+	case MAIL_CONFIG_SIG_EVENT_NAME_CHANGED: {
+
+		GtkWidget *menu;
+		GtkWidget *mi;
+
+		printf ("gui NAME CHANGED\n");
+		menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_text));
+		gtk_widget_ref (menu);
+		gtk_option_menu_remove_menu (GTK_OPTION_MENU (gui->sig_option_text));
+		mi = g_list_nth_data (GTK_MENU_SHELL (menu)->children, sig_get_index (sig));
+		gtk_label_set_text (GTK_LABEL (GTK_BIN (mi)->child), sig->name);
+		gtk_option_menu_set_menu (GTK_OPTION_MENU (gui->sig_option_text), menu);
+		gtk_widget_unref (menu);
+		gtk_option_menu_set_history (GTK_OPTION_MENU (gui->sig_option_text), sig_get_gui_index (gui, TRUE));
+
+		menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_html));
+		gtk_widget_ref (menu);
+		gtk_option_menu_remove_menu (GTK_OPTION_MENU (gui->sig_option_html));
+		mi = g_list_nth_data (GTK_MENU_SHELL (menu)->children, sig_get_index (sig));
+		gtk_label_set_text (GTK_LABEL (GTK_BIN (mi)->child), sig->name);
+		gtk_option_menu_set_menu (GTK_OPTION_MENU (gui->sig_option_html), menu);
+		gtk_widget_unref (menu);
+		gtk_option_menu_set_history (GTK_OPTION_MENU (gui->sig_option_html), sig_get_gui_index (gui, FALSE));
+
+		break;
+	}
+	case MAIL_CONFIG_SIG_EVENT_DELETED: {
+
+		GtkWidget *menu;
+		GtkWidget *mi;
+
+		printf ("gui DELETED\n");
+
+		if (sig == gui->text_signature) {
+			gui->text_signature = NULL;
+			gtk_option_menu_set_history (GTK_OPTION_MENU (gui->sig_option_text), sig_get_gui_index (gui, TRUE));
+		}
+
+		if (sig == gui->html_signature) {
+			gui->html_signature = NULL;
+			gtk_option_menu_set_history (GTK_OPTION_MENU (gui->sig_option_html), sig_get_gui_index (gui, FALSE));
+		}
+
+		menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_text));
+		mi = g_list_nth_data (GTK_MENU_SHELL (menu)->children, sig_get_index (sig));
+		gtk_container_remove (GTK_CONTAINER (menu), mi);
+
+		menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_html));
+		mi = g_list_nth_data (GTK_MENU_SHELL (menu)->children, sig_get_index (sig));
+		gtk_container_remove (GTK_CONTAINER (menu), mi);
+
+		break;
+	}
+	case MAIL_CONFIG_SIG_EVENT_RANDOM_ON: {
+
+		GtkWidget *menu;
+		GtkWidget *mi;
+
+		printf ("gui RANDOM ON\n");
+
+		mi = gtk_menu_item_new_with_label (_("Random"));
+		menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_text));
+		gtk_menu_insert (GTK_MENU (menu), mi, 1);
+		gtk_widget_show (mi);
+
+		mi = gtk_menu_item_new_with_label (_("Random"));
+		menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_html));
+		gtk_menu_insert (GTK_MENU (menu), mi, 1);
+		gtk_widget_show (mi);
+
+		break;
+	}
+	case MAIL_CONFIG_SIG_EVENT_RANDOM_OFF: {
+
+		GtkWidget *menu;
+		GtkWidget *mi;
+
+		printf ("gui RANDOM OFF\n");
+
+		if (gui->text_random) {
+			gui->text_random = FALSE;
+			gtk_option_menu_set_history (GTK_OPTION_MENU (gui->sig_option_text), sig_get_gui_index (gui, TRUE));
+		}
+
+		if (gui->html_random) {
+			gui->html_random = FALSE;
+			gtk_option_menu_set_history (GTK_OPTION_MENU (gui->sig_option_html), sig_get_gui_index (gui, FALSE));
+		}
+
+		menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_text));
+		mi = g_list_nth_data (GTK_MENU_SHELL (menu)->children, 1);
+		gtk_container_remove (GTK_CONTAINER (menu), mi);
+
+		menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_html));
+		mi = g_list_nth_data (GTK_MENU_SHELL (menu)->children, 1);
+		gtk_container_remove (GTK_CONTAINER (menu), mi);
+
+		break;
+	}
+	default:
+		;
+	}
+}
+
+static void
+prepare_signatures (MailAccountGui *gui)
+{
+	gui->sig_option_text = glade_xml_get_widget (gui->xml, "option-sig-text");
+	gui->sig_option_html = glade_xml_get_widget (gui->xml, "option-sig-html");
+
+	sig_fill_options (gui);
+
+	gtk_signal_connect (GTK_OBJECT (gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_text))),
+			    "selection-done", sig_changed_text, gui);
+	gtk_signal_connect (GTK_OBJECT (gtk_option_menu_get_menu (GTK_OPTION_MENU (gui->sig_option_html))),
+			    "selection-done", sig_changed_html, gui);
+
+	gui->sig_new_text = glade_xml_get_widget (gui->xml, "button-sig-new-text");
+	gtk_signal_connect (GTK_OBJECT (gui->sig_new_text), "clicked", GTK_SIGNAL_FUNC (sig_new_text), gui);
+	gui->sig_new_html = glade_xml_get_widget (gui->xml, "button-sig-new-html");
+	gtk_signal_connect (GTK_OBJECT (gui->sig_new_html), "clicked", GTK_SIGNAL_FUNC (sig_new_html), gui);
+	gui->sig_edit_text = glade_xml_get_widget (gui->xml, "button-sig-edit-text");
+	gtk_signal_connect (GTK_OBJECT (gui->sig_edit_text), "clicked", GTK_SIGNAL_FUNC (sig_edit_text), gui);
+	gui->sig_edit_html = glade_xml_get_widget (gui->xml, "button-sig-edit-html");
+	gtk_signal_connect (GTK_OBJECT (gui->sig_edit_html), "clicked", GTK_SIGNAL_FUNC (sig_edit_html), gui);
+
+	if (!gui->dialog) {
+		gtk_widget_hide (glade_xml_get_widget (gui->xml, "label-sig-text"));
+		gtk_widget_hide (glade_xml_get_widget (gui->xml, "label-sig-html"));
+		gtk_widget_hide (gui->sig_option_text);
+		gtk_widget_hide (gui->sig_option_html);
+		gtk_widget_hide (gui->sig_new_text);
+		gtk_widget_hide (gui->sig_new_html);
+		gtk_widget_hide (gui->sig_edit_text);
+		gtk_widget_hide (gui->sig_edit_html);
+	} else {
+		mail_config_signature_register_client ((MailConfigSignatureClient) sig_event_client, gui);
+	}
+}
+
 MailAccountGui *
-mail_account_gui_new (MailConfigAccount *account)
+mail_account_gui_new (MailConfigAccount *account, MailAccountsDialog *dialog)
 {
 	MailAccountGui *gui;
 	
 	gui = g_new0 (MailAccountGui, 1);
 	gui->account = account;
+	gui->dialog = dialog;
 	gui->xml = glade_xml_new (EVOLUTION_GLADEDIR "/mail-config.glade", NULL);
 	
 	/* Management */
@@ -1312,21 +1377,8 @@ mail_account_gui_new (MailConfigAccount *account)
 	gui->full_name = GTK_ENTRY (glade_xml_get_widget (gui->xml, "identity_full_name"));
 	gui->email_address = GTK_ENTRY (glade_xml_get_widget (gui->xml, "identity_address"));
 	gui->organization = GTK_ENTRY (glade_xml_get_widget (gui->xml, "identity_organization"));
-	gui->signature = GNOME_FILE_ENTRY (glade_xml_get_widget (gui->xml, "fileentry_signature"));
-	gui->html_signature = GNOME_FILE_ENTRY (glade_xml_get_widget (gui->xml, "fileentry_html_signature"));
-	gui->has_html_signature = GTK_TOGGLE_BUTTON (glade_xml_get_widget (gui->xml, "check_html_signature"));
-	gnome_file_entry_set_default_path (gui->signature, g_get_home_dir ());
-	gnome_file_entry_set_default_path (gui->html_signature, g_get_home_dir ());
-	gui->edit_signature = GTK_BUTTON (glade_xml_get_widget (gui->xml, "button_edit_signature"));
-	gtk_widget_set_sensitive (GTK_WIDGET (gui->edit_signature), FALSE);
-	gui->edit_html_signature = GTK_BUTTON (glade_xml_get_widget (gui->xml, "button_edit_html_signature"));
-	gtk_widget_set_sensitive (GTK_WIDGET (gui->edit_html_signature), FALSE);
-	
-	gtk_signal_connect (GTK_OBJECT (gnome_file_entry_gtk_entry (gui->signature)), "changed", signature_changed, gui);
-	gtk_signal_connect (GTK_OBJECT (gnome_file_entry_gtk_entry (gui->html_signature)), "changed",
-			    html_signature_changed, gui);
-	gtk_signal_connect (GTK_OBJECT (gui->edit_signature), "clicked", edit_signature, gui);
-	gtk_signal_connect (GTK_OBJECT (gui->edit_html_signature), "clicked", edit_html_signature, gui);
+
+	prepare_signatures (gui);
 	
 	if (account->id) {
 		if (account->id->name)
@@ -1335,17 +1387,8 @@ mail_account_gui_new (MailConfigAccount *account)
 			gtk_entry_set_text (gui->email_address, account->id->address);
 		if (account->id->organization)
 			e_utf8_gtk_entry_set_text (gui->organization, account->id->organization);
-		if (account->id->signature) {
-			gnome_file_entry_set_default_path (gui->signature, account->id->signature);
-			gtk_entry_set_text (GTK_ENTRY (gnome_file_entry_gtk_entry (gui->signature)),
-					    account->id->signature);
-		}
-		if (account->id->html_signature) {
-			gnome_file_entry_set_default_path (gui->html_signature, account->id->html_signature);
-			gtk_entry_set_text (GTK_ENTRY (gnome_file_entry_gtk_entry (gui->html_signature)),
-					    account->id->html_signature);
-		}
-		gtk_toggle_button_set_active (gui->has_html_signature, account->id->has_html_signature);
+
+		setup_signatures (gui);
 	}
 	
 	/* Source */
@@ -1755,10 +1798,9 @@ mail_account_gui_save (MailAccountGui *gui)
 	account->id->name = e_utf8_gtk_entry_get_text (gui->full_name);
 	account->id->address = e_utf8_gtk_entry_get_text (gui->email_address);
 	account->id->organization = e_utf8_gtk_entry_get_text (gui->organization);
-	account->id->signature = gnome_file_entry_get_full_path (gui->signature, TRUE);
-	account->id->html_signature = gnome_file_entry_get_full_path (gui->html_signature, TRUE);
-	account->id->has_html_signature = gtk_toggle_button_get_active (gui->has_html_signature);
-	
+
+	sig_set_and_write (gui);
+
 	old_enabled = account->source && account->source->enabled;
 	service_destroy (account->source);
 	account->source = g_new0 (MailConfigService, 1);
@@ -1849,6 +1891,9 @@ mail_account_gui_save (MailAccountGui *gui)
 void
 mail_account_gui_destroy (MailAccountGui *gui)
 {
+	if (gui->dialog)
+		mail_config_signature_unregister_client ((MailConfigSignatureClient) sig_event_client, gui);
+
 	gtk_object_unref (GTK_OBJECT (gui->xml));
 	if (gui->extra_config)
 		g_hash_table_destroy (gui->extra_config);
diff --git a/mail/mail-account-gui.h b/mail/mail-account-gui.h
index 8410fb93e4..e7bd203caf 100644
--- a/mail/mail-account-gui.h
+++ b/mail/mail-account-gui.h
@@ -36,6 +36,7 @@ extern "C" {
 #include 
 
 #include "mail-config.h"
+#include "mail-accounts.h"
 
 typedef struct {
 	GtkOptionMenu *type;
@@ -63,18 +64,26 @@ typedef struct {
 typedef struct {
 	GtkWidget *top;
 	MailConfigAccount *account;
+	MailAccountsDialog *dialog;
 	GladeXML *xml;
 	
 	/* identity */
 	GtkEntry *full_name;
 	GtkEntry *email_address;
 	GtkEntry *organization;
-	GnomeFileEntry *signature;
-	GnomeFileEntry *html_signature;
-	GtkToggleButton *has_html_signature;
-	GtkButton *edit_signature;
-	GtkButton *edit_html_signature;
-	
+
+	/* signatures */
+	GtkWidget *sig_option_text;
+	GtkWidget *sig_option_html;
+	GtkWidget *sig_new_text;
+	GtkWidget *sig_new_html;
+	GtkWidget *sig_edit_text;
+	GtkWidget *sig_edit_html;
+	MailConfigSignature *text_signature;
+	gboolean text_random;
+	MailConfigSignature *html_signature;
+	gboolean html_random;
+
 	/* incoming mail */
 	MailAccountGuiService source;
 	GtkToggleButton *source_auto_check;
@@ -113,7 +122,7 @@ typedef struct {
 } MailAccountGui;
 
 
-MailAccountGui *mail_account_gui_new (MailConfigAccount *account);
+MailAccountGui *mail_account_gui_new (MailConfigAccount *account, MailAccountsDialog *dialog);
 void mail_account_gui_setup (MailAccountGui *gui, GtkWidget *top);
 gboolean mail_account_gui_save (MailAccountGui *gui);
 void mail_account_gui_destroy (MailAccountGui *gui);
diff --git a/mail/mail-accounts.c b/mail/mail-accounts.c
index eb74aa70ed..d8573221f6 100644
--- a/mail/mail-accounts.c
+++ b/mail/mail-accounts.c
@@ -33,6 +33,7 @@
 #include 
 
 #include 
+#include 
 
 #include "widgets/misc/e-charset-picker.h"
 
@@ -46,6 +47,7 @@
 #endif
 #include "mail-send-recv.h"
 #include "mail-session.h"
+#include "mail-signature-editor.h"
 
 #include "art/mark.xpm"
 
@@ -268,7 +270,7 @@ mail_edit (GtkButton *button, gpointer data)
 			MailConfigAccount *account;
 			
 			account = gtk_clist_get_row_data (dialog->mail_accounts, dialog->accounts_row);
-			editor = mail_account_editor_new (account, GTK_WINDOW (dialog));
+			editor = mail_account_editor_new (account, GTK_WINDOW (dialog), dialog);
 			gtk_signal_connect (GTK_OBJECT (editor), "destroy",
 					    GTK_SIGNAL_FUNC (mail_editor_destroyed),
 					    dialog);
@@ -797,6 +799,8 @@ charset_menu_deactivate (GtkWidget *menu, gpointer data)
 	}
 }
 
+static void sig_event_client (MailConfigSigEvent event, MailConfigSignature *sig, MailAccountsDialog *dialog);
+
 static void
 dialog_destroy (GtkWidget *dialog, gpointer user_data)
 {
@@ -810,6 +814,372 @@ dialog_destroy (GtkWidget *dialog, gpointer user_data)
 	if (news_editor)
 		gtk_widget_destroy (GTK_WIDGET (news_editor));
 #endif
+	mail_config_signature_unregister_client ((MailConfigSignatureClient) sig_event_client, dialog);
+	gtk_widget_unref (((MailAccountsDialog *) dialog)->sig_advanced_button);
+	gtk_widget_unref (((MailAccountsDialog *) dialog)->sig_simple_button);
+}
+
+/* Signatures */
+
+static void
+sig_load_preview (MailAccountsDialog *dialog, MailConfigSignature *sig)
+{
+	gchar *str;
+
+	if (!sig) {
+		gtk_html_load_from_string (GTK_HTML (dialog->sig_gtk_html), " ", 1);
+		return;
+	}
+
+	mail_config_signature_run_script (sig->script);
+	str = e_msg_composer_get_sig_file_content (sig->filename, sig->html);
+	if (!str)
+		str = g_strdup (" ");
+
+	/* printf ("HTML: %s\n", str); */
+	if (sig->html)
+		gtk_html_load_from_string (GTK_HTML (dialog->sig_gtk_html), str, strlen (str));
+	else {
+		GtkHTMLStream *stream;
+		gint len;
+
+		len = strlen (str);
+		stream = gtk_html_begin (GTK_HTML (dialog->sig_gtk_html));
+		gtk_html_write (GTK_HTML (dialog->sig_gtk_html), stream, "
", 5);
+		if (len)
+			gtk_html_write (GTK_HTML (dialog->sig_gtk_html), stream, str, len);
+		gtk_html_write (GTK_HTML (dialog->sig_gtk_html), stream, "
", 6); + gtk_html_end (GTK_HTML (dialog->sig_gtk_html), stream, GTK_HTML_STREAM_OK); + } + + g_free (str); +} + +static inline void +sig_write_and_update_preview (MailAccountsDialog *dialog, MailConfigSignature *sig) +{ + sig_load_preview (dialog, sig); + mail_config_signature_write (sig); +} + +static MailConfigSignature * +sig_current_sig (MailAccountsDialog *dialog) +{ + return gtk_clist_get_row_data (GTK_CLIST (dialog->sig_clist), dialog->sig_row); +} + +static void +sig_edit (GtkWidget *w, MailAccountsDialog *dialog) +{ + MailConfigSignature *sig = sig_current_sig (dialog); + + if (sig->filename && *sig->filename) + mail_signature_editor (sig->filename, sig->html); + else + e_notice (GTK_WINDOW (dialog), GNOME_MESSAGE_BOX_ERROR, + _("Please specify signature filename\nin Andvanced section of signature settings.")); +} + +MailConfigSignature * +mail_accounts_dialog_new_signature (MailAccountsDialog *dialog, gboolean html) +{ + MailConfigSignature *sig; + gchar *name [1]; + gint row; + + sig = mail_config_signature_add (html); + + name [0] = sig->name; + row = gtk_clist_append (GTK_CLIST (dialog->sig_clist), name); + gtk_clist_set_row_data (GTK_CLIST (dialog->sig_clist), row, sig); + gtk_clist_select_row (GTK_CLIST (dialog->sig_clist), row, 0); + gtk_widget_grab_focus (dialog->sig_name); + + sig_edit (NULL, dialog); + + return sig; +} + +static void sig_row_unselect (GtkWidget *w, gint row, gint col, GdkEvent *event, MailAccountsDialog *dialog); + +static void +sig_delete (GtkWidget *w, MailAccountsDialog *dialog) +{ + MailConfigSignature *sig = sig_current_sig (dialog); + + gtk_clist_remove (GTK_CLIST (dialog->sig_clist), dialog->sig_row); + mail_config_signature_delete (sig); + if (dialog->sig_row < GTK_CLIST (dialog->sig_clist)->rows) + gtk_clist_select_row (GTK_CLIST (dialog->sig_clist), dialog->sig_row, 0); + else if (dialog->sig_row) + gtk_clist_select_row (GTK_CLIST (dialog->sig_clist), dialog->sig_row - 1, 0); + else + sig_row_unselect (dialog->sig_clist, dialog->sig_row, 0, NULL, dialog); +} + +static void +sig_add (GtkWidget *w, MailAccountsDialog *dialog) +{ + mail_accounts_dialog_new_signature (dialog, FALSE); +} + +static void +sig_level (GtkWidget *w, MailAccountsDialog *dialog) +{ + GtkWidget *button; + gboolean level; + + if (!GTK_WIDGET_VISIBLE (w)) + return; + + level = w == dialog->sig_advanced_button; + + button = level ? dialog->sig_simple_button : dialog->sig_advanced_button; + gtk_widget_hide (w); + gtk_container_remove (GTK_CONTAINER (dialog->sig_level_bbox), w); + gtk_box_pack_start (GTK_BOX (dialog->sig_level_bbox), button, FALSE, 0, FALSE); + gtk_widget_show (button); + + level ? gtk_widget_hide (dialog->sig_preview) : gtk_widget_show (dialog->sig_preview); + level ? gtk_widget_show (dialog->sig_advanced_table) : gtk_widget_hide (dialog->sig_advanced_table); +} + +static void +sig_row_select (GtkWidget *w, gint row, gint col, GdkEvent *event, MailAccountsDialog *dialog) +{ + MailConfigSignature *sig; + + printf ("sig_row_select\n"); + gtk_widget_set_sensitive (dialog->sig_add, TRUE); + gtk_widget_set_sensitive (dialog->sig_delete, TRUE); + gtk_widget_set_sensitive (dialog->sig_edit, TRUE); + gtk_widget_set_sensitive (dialog->sig_name, TRUE); + gtk_widget_set_sensitive (dialog->sig_random, TRUE); + gtk_widget_set_sensitive (dialog->sig_filename, TRUE); + gtk_widget_set_sensitive (dialog->sig_script, TRUE); + gtk_widget_set_sensitive (dialog->sig_html, TRUE); + + dialog->sig_switch = TRUE; + sig = gtk_clist_get_row_data (GTK_CLIST (dialog->sig_clist), row); + if (sig) { + if (sig->name) + gtk_entry_set_text (GTK_ENTRY (dialog->sig_name), sig->name); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->sig_random), sig->random); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->sig_html), sig->html); + if (sig->filename) + gtk_entry_set_text (GTK_ENTRY (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (dialog->sig_filename))), + sig->filename); + if (sig->script) + gtk_entry_set_text (GTK_ENTRY (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (dialog->sig_script))), + sig->script); + } + dialog->sig_switch = FALSE; + dialog->sig_row = row; + + sig_load_preview (dialog, sig); +} + +static void +sig_row_unselect (GtkWidget *w, gint row, gint col, GdkEvent *event, MailAccountsDialog *dialog) +{ + printf ("sig_row_unselect\n"); + gtk_widget_set_sensitive (dialog->sig_add, FALSE); + gtk_widget_set_sensitive (dialog->sig_delete, FALSE); + gtk_widget_set_sensitive (dialog->sig_edit, FALSE); + gtk_widget_set_sensitive (dialog->sig_name, FALSE); + gtk_widget_set_sensitive (dialog->sig_random, FALSE); + gtk_widget_set_sensitive (dialog->sig_filename, FALSE); + gtk_widget_set_sensitive (dialog->sig_script, FALSE); + + dialog->sig_switch = TRUE; + gtk_entry_set_text (GTK_ENTRY (dialog->sig_name), ""); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->sig_random), FALSE); + gtk_entry_set_text (GTK_ENTRY (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (dialog->sig_filename))), ""); + gtk_entry_set_text (GTK_ENTRY (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (dialog->sig_script))), ""); + dialog->sig_switch = FALSE; +} + +static void +sig_fill_clist (GtkWidget *clist) +{ + GList *l; + gchar *name [1]; + gint row; + + gtk_clist_freeze (GTK_CLIST (clist)); + for (l = mail_config_get_signature_list (); l; l = l->next) { + name [0] = ((MailConfigSignature *) l->data)->name; + row = gtk_clist_append (GTK_CLIST (clist), name); + gtk_clist_set_row_data (GTK_CLIST (clist), row, l->data); + } + gtk_clist_thaw (GTK_CLIST (clist)); +} + +static void +sig_name_changed (GtkWidget *w, MailAccountsDialog *dialog) +{ + MailConfigSignature *sig = sig_current_sig (dialog); + + if (dialog->sig_switch) + return; + + mail_config_signature_set_name (sig, gtk_entry_get_text (GTK_ENTRY (dialog->sig_name))); + gtk_clist_set_text (GTK_CLIST (dialog->sig_clist), dialog->sig_row, 0, sig->name); + + sig_write_and_update_preview (dialog, sig); +} + +static void +sig_random_toggled (GtkWidget *w, MailAccountsDialog *dialog) +{ + MailConfigSignature *sig = sig_current_sig (dialog); + + if (dialog->sig_switch) + return; + + mail_config_signature_set_random (sig, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->sig_random))); + + sig_write_and_update_preview (dialog, sig); +} + +static void +sig_html_toggled (GtkWidget *w, MailAccountsDialog *dialog) +{ + MailConfigSignature *sig = sig_current_sig (dialog); + + if (dialog->sig_switch) + return; + + sig->html = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->sig_html)); + + sig_write_and_update_preview (dialog, sig); +} + +static void +sig_filename_changed (GtkWidget *w, MailAccountsDialog *dialog) +{ + MailConfigSignature *sig = sig_current_sig (dialog); + + if (dialog->sig_switch) + return; + + mail_config_signature_set_filename (sig, gnome_file_entry_get_full_path (GNOME_FILE_ENTRY (dialog->sig_filename), + FALSE)); + sig_write_and_update_preview (dialog, sig); +} + +static void +sig_script_changed (GtkWidget *w, MailAccountsDialog *dialog) +{ + MailConfigSignature *sig = sig_current_sig (dialog); + + if (dialog->sig_switch) + return; + + g_free (sig->script); + sig->script = g_strdup (gnome_file_entry_get_full_path (GNOME_FILE_ENTRY (dialog->sig_script), FALSE)); + + sig_write_and_update_preview (dialog, sig); +} + +static void +url_requested (GtkHTML *html, const gchar *url, GtkHTMLStream *handle) +{ + GtkHTMLStreamStatus status; + gint fd; + + if (!strncmp (url, "file:", 5)) + url += 5; + + fd = open (url, O_RDONLY); + status = GTK_HTML_STREAM_OK; + if (fd != -1) { + ssize_t size; + void *buf = alloca (1 << 7); + while ((size = read (fd, buf, 1 << 7))) { + if (size == -1) { + status = GTK_HTML_STREAM_ERROR; + break; + } else + gtk_html_write (html, handle, (const gchar *) buf, size); + } + } else + status = GTK_HTML_STREAM_ERROR; + gtk_html_end (html, handle, status); +} + +static void +sig_event_client (MailConfigSigEvent event, MailConfigSignature *sig, MailAccountsDialog *dialog) +{ + switch (event) { + case MAIL_CONFIG_SIG_EVENT_NAME_CHANGED: + printf ("accounts NAME CHANGED\n"); + break; + default: + ; + } +} + +static void +signatures_page_construct (MailAccountsDialog *dialog, GladeXML *gui) +{ + dialog->sig_add = glade_xml_get_widget (gui, "button-sig-add"); + gtk_signal_connect (GTK_OBJECT (dialog->sig_add), "clicked", GTK_SIGNAL_FUNC (sig_add), dialog); + + dialog->sig_delete = glade_xml_get_widget (gui, "button-sig-delete"); + gtk_signal_connect (GTK_OBJECT (dialog->sig_delete), "clicked", GTK_SIGNAL_FUNC (sig_delete), dialog); + + dialog->sig_edit = glade_xml_get_widget (gui, "button-sig-edit"); + gtk_signal_connect (GTK_OBJECT (dialog->sig_edit), "clicked", GTK_SIGNAL_FUNC (sig_edit), dialog); + + dialog->sig_advanced_button = glade_xml_get_widget (gui, "button-sig-advanced"); + gtk_signal_connect (GTK_OBJECT (dialog->sig_advanced_button), "clicked", GTK_SIGNAL_FUNC (sig_level), dialog); + + dialog->sig_simple_button = glade_xml_get_widget (gui, "button-sig-simple"); + gtk_signal_connect (GTK_OBJECT (dialog->sig_simple_button), "clicked", GTK_SIGNAL_FUNC (sig_level), dialog); + dialog->sig_level_bbox = glade_xml_get_widget (gui, "vbbox-sig-level"); + + gtk_widget_ref (dialog->sig_advanced_button); + gtk_widget_ref (dialog->sig_simple_button); + gtk_widget_hide (dialog->sig_simple_button); + gtk_container_remove (GTK_CONTAINER (dialog->sig_level_bbox), dialog->sig_simple_button); + + dialog->sig_clist = glade_xml_get_widget (gui, "clist-sig"); + sig_fill_clist (dialog->sig_clist); + gtk_signal_connect (GTK_OBJECT (dialog->sig_clist), "select_row", GTK_SIGNAL_FUNC (sig_row_select), dialog); + gtk_signal_connect (GTK_OBJECT (dialog->sig_clist), "unselect_row", GTK_SIGNAL_FUNC (sig_row_unselect), dialog); + + dialog->sig_name = glade_xml_get_widget (gui, "entry-sig-name"); + gtk_signal_connect (GTK_OBJECT (dialog->sig_name), "changed", GTK_SIGNAL_FUNC (sig_name_changed), dialog); + + dialog->sig_html = glade_xml_get_widget (gui, "check-sig-html"); + gtk_signal_connect (GTK_OBJECT (dialog->sig_html), "toggled", GTK_SIGNAL_FUNC (sig_html_toggled), dialog); + + dialog->sig_random = glade_xml_get_widget (gui, "check-sig-random"); + gtk_signal_connect (GTK_OBJECT (dialog->sig_random), "toggled", GTK_SIGNAL_FUNC (sig_random_toggled), dialog); + + dialog->sig_filename = glade_xml_get_widget (gui, "file-sig-filename"); + gtk_signal_connect (GTK_OBJECT (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (dialog->sig_filename))), + "changed", GTK_SIGNAL_FUNC (sig_filename_changed), dialog); + + dialog->sig_script = glade_xml_get_widget (gui, "file-sig-script"); + gtk_signal_connect (GTK_OBJECT (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (dialog->sig_script))), + "changed", GTK_SIGNAL_FUNC (sig_script_changed), dialog); + + dialog->sig_advanced_table = glade_xml_get_widget (gui, "table-sig-advanced"); + dialog->sig_preview = glade_xml_get_widget (gui, "frame-sig-preview"); + + /* preview GtkHTML widget */ + dialog->sig_scrolled = glade_xml_get_widget (gui, "scrolled-sig"); + dialog->sig_gtk_html = gtk_html_new (); + gtk_signal_connect (GTK_OBJECT (dialog->sig_gtk_html), "url_requested", GTK_SIGNAL_FUNC (url_requested), NULL); + gtk_widget_show (dialog->sig_gtk_html); + gtk_container_add (GTK_CONTAINER (dialog->sig_scrolled), dialog->sig_gtk_html); + + if (GTK_CLIST (dialog->sig_clist)->rows) + gtk_clist_select_row (GTK_CLIST (dialog->sig_clist), 0, 0); + + mail_config_signature_register_client ((MailConfigSignatureClient) sig_event_client, dialog); } static void @@ -954,6 +1324,9 @@ construct (MailAccountsDialog *dialog) gtk_toggle_button_set_active (dialog->prompt_unwanted_html, mail_config_get_confirm_unwanted_html ()); gtk_signal_connect (GTK_OBJECT (dialog->prompt_unwanted_html), "toggled", GTK_SIGNAL_FUNC (prompt_unwanted_html_toggled), dialog); + + /* Signatures page */ + signatures_page_construct (dialog, gui); /* Other page */ dialog->pgp_path = GNOME_FILE_ENTRY (glade_xml_get_widget (gui, "filePgpPath")); diff --git a/mail/mail-accounts.h b/mail/mail-accounts.h index 83134fc6d4..8d29746a5b 100644 --- a/mail/mail-accounts.h +++ b/mail/mail-accounts.h @@ -88,6 +88,29 @@ struct _MailAccountsDialog { GtkToggleButton *prompt_bcc_only; GtkToggleButton *prompt_unwanted_html; + /* Signatures page */ + GtkWidget *sig_clist; + + GtkWidget *sig_name; + GtkWidget *sig_random; + GtkWidget *sig_filename; + GtkWidget *sig_script; + GtkWidget *sig_html; + GtkWidget *sig_scrolled; + GtkWidget *sig_gtk_html; + GtkWidget *sig_preview; + + GtkWidget *sig_add; + GtkWidget *sig_delete; + GtkWidget *sig_edit; + + GtkWidget *sig_simple_button; + GtkWidget *sig_advanced_button; + GtkWidget *sig_level_bbox; + GtkWidget *sig_advanced_table; + gboolean sig_switch; + gint sig_row; + /* Other page */ GtkToggleButton *empty_trash; GtkToggleButton *filter_log; @@ -118,6 +141,7 @@ typedef struct { GtkType mail_accounts_dialog_get_type (void); MailAccountsDialog *mail_accounts_dialog_new (GNOME_Evolution_Shell shell); +MailConfigSignature *mail_accounts_dialog_new_signature (MailAccountsDialog *dialog, gboolean html); #ifdef __cplusplus } diff --git a/mail/mail-config-druid.c b/mail/mail-config-druid.c index 41d272a626..68c745debe 100644 --- a/mail/mail-config-druid.c +++ b/mail/mail-config-druid.c @@ -696,7 +696,7 @@ get_fn (EvolutionWizard *wizard, gui->account); } - gui->gui = mail_account_gui_new (gui->account); + gui->gui = mail_account_gui_new (gui->account, NULL); /* set up signals, etc */ gtk_signal_connect (GTK_OBJECT (gui->gui->account_name), diff --git a/mail/mail-config.c b/mail/mail-config.c index 2cc841b0d0..2e6d539f93 100644 --- a/mail/mail-config.c +++ b/mail/mail-config.c @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Authors: Jeffrey Stedfast + * Radek Doulik * * Copyright 2001 Ximian, Inc. (www.ximian.com) * @@ -113,6 +114,10 @@ typedef struct { char *notify_filename; char *last_filesel_dir; + + GList *signature_list; + gint signatures; + gint signatures_random; } MailConfig; static MailConfig *config = NULL; @@ -123,6 +128,34 @@ static MailConfig *config = NULL; static void config_read (void); static void mail_config_set_default_account_num (int new_default); +/* signatures */ +MailConfigSignature * +signature_copy (const MailConfigSignature *sig) +{ + MailConfigSignature *ns; + + g_return_val_if_fail (sig != NULL, NULL); + + ns = g_new (MailConfigSignature, 1); + + ns->id = sig->id; + ns->name = g_strdup (sig->name); + ns->filename = g_strdup (sig->filename); + ns->script = g_strdup (sig->script); + ns->random = sig->random; + ns->html = sig->html; + + return ns; +} + +void +signature_destroy (MailConfigSignature *sig) +{ + g_free (sig->name); + g_free (sig->filename); + g_free (sig->script); + g_free (sig); +} /* Identity */ MailConfigIdentity * @@ -136,10 +169,11 @@ identity_copy (const MailConfigIdentity *id) new->name = g_strdup (id->name); new->address = g_strdup (id->address); new->organization = g_strdup (id->organization); - new->signature = g_strdup (id->signature); - new->html_signature = g_strdup (id->html_signature); - new->has_html_signature = id->has_html_signature; - + new->text_signature = id->text_signature; + new->text_random = id->text_random; + new->html_signature = id->html_signature; + new->html_random = id->html_random; + return new; } @@ -152,8 +186,6 @@ identity_destroy (MailConfigIdentity *id) g_free (id->name); g_free (id->address); g_free (id->organization); - g_free (id->signature); - g_free (id->html_signature); g_free (id); } @@ -328,12 +360,238 @@ mail_config_clear (void) config->last_filesel_dir = NULL; } +static MailConfigSignature * +config_read_signature (gint i) +{ + MailConfigSignature *sig; + gchar *path, *val; + + sig = g_new0 (MailConfigSignature, 1); + + sig->id = i; + + path = g_strdup_printf ("/Mail/Signatures/name_%d", i); + val = bonobo_config_get_string (config->db, path, NULL); + g_free (path); + if (val && *val) + sig->name = val; + else + g_free (val); + + path = g_strdup_printf ("/Mail/Signatures/filename_%d", i); + val = bonobo_config_get_string (config->db, path, NULL); + g_free (path); + if (val && *val) + sig->filename = val; + else + g_free (val); + + path = g_strdup_printf ("/Mail/Signatures/script_%d", i); + val = bonobo_config_get_string (config->db, path, NULL); + g_free (path); + if (val && *val) + sig->script = val; + else + g_free (val); + + path = g_strdup_printf ("/Mail/Signatures/random_%d", i); + sig->random = bonobo_config_get_boolean_with_default (config->db, path, FALSE, NULL); + + path = g_strdup_printf ("/Mail/Signatures/html_%d", i); + sig->html = bonobo_config_get_boolean_with_default (config->db, path, FALSE, NULL); + + return sig; +} + +static void +config_read_signatures () +{ + MailConfigSignature *sig; + gint i; + + config->signature_list = NULL; + config->signatures_random = 0; + config->signatures = bonobo_config_get_long_with_default (config->db, "/Mail/Signatures/num", 0, NULL); + + for (i = 0; i < config->signatures; i ++) { + sig = config_read_signature (i); + config->signature_list = g_list_append (config->signature_list, sig); + if (sig->random) + config->signatures_random ++; + } +} + +static void +config_write_signature (MailConfigSignature *sig, gint i) +{ + gchar *path; + + printf ("config_write_signature i: %d id: %d\n", i, sig->id); + + path = g_strdup_printf ("/Mail/Signatures/name_%d", i); + bonobo_config_set_string (config->db, path, sig->name ? sig->name : "", NULL); + g_free (path); + + path = g_strdup_printf ("/Mail/Signatures/filename_%d", i); + bonobo_config_set_string (config->db, path, sig->filename ? sig->filename : "", NULL); + g_free (path); + + path = g_strdup_printf ("/Mail/Signatures/script_%d", i); + bonobo_config_set_string (config->db, path, sig->script ? sig->script : "", NULL); + g_free (path); + + path = g_strdup_printf ("/Mail/Signatures/random_%d", i); + bonobo_config_set_boolean (config->db, path, sig->random, NULL); + + path = g_strdup_printf ("/Mail/Signatures/html_%d", i); + bonobo_config_set_boolean (config->db, path, sig->html, NULL); +} + +static void +config_write_signatures_num () +{ + bonobo_config_set_long (config->db, "/Mail/Signatures/num", config->signatures, NULL); +} + +static void +config_write_signatures () +{ + GList *l; + gint id; + + for (id = 0, l = config->signature_list; l; l = l->next, id ++) { + config_write_signature ((MailConfigSignature *) l->data, id); + } + + config_write_signatures_num (); +} + +static MailConfigSignature * +lookup_signature (gint i) +{ + MailConfigSignature *sig; + GList *l; + + if (i == -1) + return NULL; + + for (l = config->signature_list; l; l = l->next) { + sig = (MailConfigSignature *) l->data; + if (sig->id == i) + return sig; + } + + return NULL; +} + +static void +config_write_imported_signature (gchar *filename, gint i, gboolean html) +{ + MailConfigSignature *sig = g_new0 (MailConfigSignature, 1); + gchar *name; + + name = strrchr (filename, '/'); + if (!name) + name = filename; + else + name ++; + + sig->name = g_strdup (name); + sig->filename = filename; + sig->html = html; + + config_write_signature (sig, i); + signature_destroy (sig); +} + +static void +config_import_old_signatures () +{ + gint num; + + num = bonobo_config_get_long_with_default (config->db, "/Mail/Signatures/num", -1, NULL); + + if (num == -1) { + /* there are no signatures defined + * look for old config to create new ones from old ones + */ + + GHashTable *cache; + gint i, accounts; + + cache = g_hash_table_new (g_str_hash, g_str_equal); + accounts = bonobo_config_get_long_with_default (config->db, "/Mail/Accounts/num", 0, NULL); + num = 0; + for (i = 0; i < accounts; i ++) { + gchar *path, *val; + + /* read text signature file */ + path = g_strdup_printf ("/Mail/Accounts/identity_signature_%d", i); + val = bonobo_config_get_string (config->db, path, NULL); + g_free (path); + if (val && *val) { + + gint id; + gpointer orig_key, node_val; + + if (g_hash_table_lookup_extended (cache, val, &orig_key, &node_val)) { + id = GPOINTER_TO_INT (node_val); + } else { + g_hash_table_insert (cache, g_strdup (val), GINT_TO_POINTER (id)); + config_write_imported_signature (val, num, FALSE); + id = num; + num ++; + } + + /* set new text signature to this identity */ + path = g_strdup_printf ("/Mail/Accounts/identity_signature_text_%d", i); + bonobo_config_set_long (config->db, path, id, NULL); + g_free (path); + } else + g_free (val); + + path = g_strdup_printf ("/Mail/Accounts/identity_has_html_signature_%d", i); + if (bonobo_config_get_boolean_with_default (config->db, path, FALSE, NULL)) { + g_free (path); + path = g_strdup_printf ("/Mail/Accounts/identity_html_signature_%d", i); + val = bonobo_config_get_string (config->db, path, NULL); + if (val && *val) { + + gint id; + gpointer orig_key, node_val; + + if (g_hash_table_lookup_extended (cache, val, &orig_key, &node_val)) { + id = GPOINTER_TO_INT (node_val); + } else { + g_hash_table_insert (cache, g_strdup (val), GINT_TO_POINTER (id)); + config_write_imported_signature (val, num, TRUE); + id = num; + num ++; + } + + /* set new html signature to this identity */ + g_free (path); + path = g_strdup_printf ("/Mail/Accounts/identity_signature_html_%d", i); + bonobo_config_set_long (config->db, path, id, NULL); + } else + g_free (val); + } + g_free (path); + } + bonobo_config_set_long (config->db, "/Mail/Signatures/num", num, NULL); + g_hash_table_destroy (cache); + } +} + static void config_read (void) { int len, i, default_num; mail_config_clear (); + + config_import_old_signatures (); + config_read_signatures (); len = bonobo_config_get_long_with_default (config->db, "/Mail/Accounts/num", 0, NULL); @@ -467,17 +725,23 @@ config_read (void) id->organization = bonobo_config_get_string (config->db, path, NULL); g_free (path); - path = g_strdup_printf ("/Mail/Accounts/identity_signature_%d", i); - id->signature = bonobo_config_get_string (config->db, path, NULL); + /* id signatures */ + path = g_strdup_printf ("/Mail/Accounts/identity_signature_text_%d", i); + id->text_signature = lookup_signature (bonobo_config_get_long_with_default (config->db, path, -1, NULL)); g_free (path); - path = g_strdup_printf ("/Mail/Accounts/identity_html_signature_%d", i); - id->html_signature = bonobo_config_get_string (config->db, path, NULL); + + path = g_strdup_printf ("/Mail/Accounts/identity_signature_html_%d", i); + id->html_signature = lookup_signature (bonobo_config_get_long_with_default (config->db, path, -1, NULL)); g_free (path); - path = g_strdup_printf ("/Mail/Accounts/identity_has_html_signature_%d", i); - id->has_html_signature = bonobo_config_get_boolean_with_default ( - config->db, path, FALSE, NULL); + + path = g_strdup_printf ("/Mail/Accounts/identity_signature_text_random_%d", i); + id->text_random = bonobo_config_get_boolean_with_default (config->db, path, FALSE, NULL); g_free (path); - + + path = g_strdup_printf ("/Mail/Accounts/identity_signature_html_random_%d", i); + id->html_random = bonobo_config_get_boolean_with_default (config->db, path, FALSE, NULL); + g_free (path); + /* get the source */ source = g_new0 (MailConfigService, 1); @@ -687,6 +951,42 @@ config_read (void) #define bonobo_config_set_string_wrapper(db, path, val, ev) bonobo_config_set_string (db, path, val ? val : "", ev) +void +mail_config_write_account_sig (MailConfigAccount *account, gint i) +{ + char *path; + + if (i == -1) { + GSList *link; + + link = g_slist_find (config->accounts, account); + if (!link) { + g_warning ("Can't find account in accounts list"); + return; + } + i = g_slist_position (config->accounts, link); + } + + /* id signatures */ + path = g_strdup_printf ("/Mail/Accounts/identity_signature_text_%d", i); + bonobo_config_set_long (config->db, path, account->id->text_signature + ? account->id->text_signature->id : -1, NULL); + g_free (path); + + path = g_strdup_printf ("/Mail/Accounts/identity_signature_html_%d", i); + bonobo_config_set_long (config->db, path, account->id->html_signature + ? account->id->html_signature->id : -1, NULL); + g_free (path); + + path = g_strdup_printf ("/Mail/Accounts/identity_signature_text_random_%d", i); + bonobo_config_set_boolean (config->db, path, account->id->text_random, NULL); + g_free (path); + + path = g_strdup_printf ("/Mail/Accounts/identity_signature_html_random_%d", i); + bonobo_config_set_boolean (config->db, path, account->id->html_random, NULL); + g_free (path); +} + void mail_config_write (void) { @@ -705,6 +1005,8 @@ mail_config_write (void) CORBA_exception_init (&ev); Bonobo_ConfigDatabase_sync (config->db, &ev); + config_write_signatures (); + len = g_slist_length (config->accounts); bonobo_config_set_long (config->db, "/Mail/Accounts/num", len, NULL); @@ -802,18 +1104,8 @@ mail_config_write (void) bonobo_config_set_string_wrapper (config->db, path, account->id->organization, NULL); g_free (path); - path = g_strdup_printf ("/Mail/Accounts/identity_signature_%d", i); - bonobo_config_set_string_wrapper (config->db, path, account->id->signature, NULL); - g_free (path); - - path = g_strdup_printf ("/Mail/Accounts/identity_html_signature_%d", i); - bonobo_config_set_string_wrapper (config->db, path, account->id->html_signature, NULL); - g_free (path); - - path = g_strdup_printf ("/Mail/Accounts/identity_has_html_signature_%d", i); - bonobo_config_set_boolean (config->db, path, account->id->has_html_signature, NULL); - g_free (path); - + mail_config_write_account_sig (account, i); + /* source info */ path = g_strdup_printf ("/Mail/Accounts/source_url_%d", i); bonobo_config_set_string_wrapper (config->db, path, account->source->url, NULL); @@ -2438,9 +2730,6 @@ impl_GNOME_Evolution_MailConfig_addAccount (PortableServer_Servant servant, mail_id->name = g_strdup (id.name); mail_id->address = g_strdup (id.address); mail_id->organization = g_strdup (id.organization); - mail_id->signature = g_strdup (id.signature); - mail_id->html_signature = g_strdup (id.html_signature); - mail_id->has_html_signature = id.has_html_signature; mail_account->id = mail_id; @@ -2526,3 +2815,225 @@ evolution_mail_config_factory_init (void) bonobo_running_context_auto_exit_unref (BONOBO_OBJECT (factory)); return TRUE; } + +GList * +mail_config_get_signature_list (void) +{ + return config->signature_list; +} + +static gchar * +get_new_signature_filename () +{ + struct stat st_buf; + gchar *filename; + gint i; + + filename = g_strconcat (evolution_dir, "/signatures", NULL); + if (lstat (filename, &st_buf)) { + if (errno == ENOENT) { + if (mkdir (filename, 0700)) + g_warning ("Fatal problem creating %s/signatures directory.", evolution_dir); + } else + g_warning ("Fatal problem with %s/signatures directory.", evolution_dir); + } + g_free (filename); + + for (i = 0; ; i ++) { + filename = g_strdup_printf ("%s/signatures/signature-%d", evolution_dir, i); + if (lstat (filename, &st_buf) == - 1 && errno == ENOENT) { + return filename; + } + g_free (filename); + } + + return NULL; +} + +MailConfigSignature * +mail_config_signature_add (gboolean html) +{ + MailConfigSignature *sig; + + sig = g_new0 (MailConfigSignature, 1); + + /* printf ("mail_config_signature_add %d\n", config->signatures); */ + sig->id = config->signatures; + sig->name = g_strdup (_("Unnamed")); + sig->filename = get_new_signature_filename (); + sig->html = html; + + config->signature_list = g_list_append (config->signature_list, sig); + config->signatures ++; + + config_write_signature (sig, sig->id); + config_write_signatures_num (); + + mail_config_signature_emit_event (MAIL_CONFIG_SIG_EVENT_ADDED, sig); + /* printf ("mail_config_signature_add end\n"); */ + + return sig; +} + +static void +delete_unused_signature_file (const gchar *filename) +{ + gint len; + + /* remove signature file if it's in evolution dir and no other signature uses it */ + len = strlen (evolution_dir); + if (filename && !strncmp (filename, evolution_dir, len)) { + GList *l; + gboolean only_one = TRUE; + + for (l = config->signature_list; l; l = l->next) { + if (((MailConfigSignature *)l->data)->filename + && !strcmp (filename, ((MailConfigSignature *)l->data)->filename)) { + only_one = FALSE; + break; + } + } + + if (only_one) { + unlink (filename); + } + } +} + +void +mail_config_signature_delete (MailConfigSignature *sig) +{ + GList *l, *next; + GSList *al; + gboolean after = FALSE; + + /* FIXME remove it from all accounts */ + + for (al = config->accounts; al; al = al->next) { + MailConfigAccount *account; + + account = (MailConfigAccount *) al->data; + + if (account->id->text_signature == sig) + account->id->text_signature = NULL; + if (account->id->html_signature == sig) + account->id->html_signature = NULL; + } + + for (l = config->signature_list; l; l = next) { + next = l->next; + if (after) + ((MailConfigSignature *) l->data)->id --; + else if (l->data == sig) { + config->signature_list = g_list_remove_link (config->signature_list, l); + after = TRUE; + config->signatures --; + if (sig->random) + config->signatures_random --; + } + } + + config_write_signatures (); + delete_unused_signature_file (sig->filename); + /* printf ("signatures: %d\n", config->signatures); */ + mail_config_signature_emit_event (MAIL_CONFIG_SIG_EVENT_DELETED, sig); + signature_destroy (sig); +} + +void +mail_config_signature_write (MailConfigSignature *sig) +{ + config_write_signature (sig, sig->id); +} + +void +mail_config_signature_set_filename (MailConfigSignature *sig, const gchar *filename) +{ + gchar *old_filename = sig->filename; + + sig->filename = g_strdup (filename); + if (old_filename) { + delete_unused_signature_file (old_filename); + g_free (old_filename); + } +} + +void +mail_config_signature_set_name (MailConfigSignature *sig, const gchar *name) +{ + g_free (sig->name); + sig->name = g_strdup (name); + + mail_config_signature_emit_event (MAIL_CONFIG_SIG_EVENT_NAME_CHANGED, sig); +} + +void +mail_config_signature_set_random (MailConfigSignature *sig, gboolean random) +{ + if (random != sig->random) { + if (random && !sig->random) { + config->signatures_random ++; + if (config->signatures_random == 1) + mail_config_signature_emit_event (MAIL_CONFIG_SIG_EVENT_RANDOM_ON, sig); + } else if (!random && sig->random) { + config->signatures_random --; + if (config->signatures_random == 0) + mail_config_signature_emit_event (MAIL_CONFIG_SIG_EVENT_RANDOM_OFF, sig); + } + sig->random = random; + } +} + +gint +mail_config_get_signatures_random (void) +{ + return config->signatures_random; +} + +static GList *clients = NULL; + +void +mail_config_signature_register_client (MailConfigSignatureClient client, gpointer data) +{ + clients = g_list_append (clients, client); + clients = g_list_append (clients, data); +} + +void +mail_config_signature_unregister_client (MailConfigSignatureClient client, gpointer data) +{ + GList *link; + + link = g_list_find (clients, data); + clients = g_list_remove_link (clients, link->prev); + clients = g_list_remove_link (clients, link); +} + +void +mail_config_signature_emit_event (MailConfigSigEvent event, MailConfigSignature *sig) +{ + GList *l, *next; + + for (l = clients; l; l = next) { + next = l->next->next; + (*((MailConfigSignatureClient) l->data)) (event, sig, l->next->data); + } +} + +void +mail_config_signature_run_script (gchar *script) +{ + if (script) { + gchar *argv[2]; + gint pid, status; + + printf ("running script %s\n", script); + argv [0] = script; + argv [1] = NULL; + pid = gnome_execute_async (NULL, 1, argv); + if (pid < 0) + gnome_error_dialog (_("Cannot execute signature script")); + else + waitpid (pid, &status, 0); + } +} diff --git a/mail/mail-config.glade b/mail/mail-config.glade index f837035d91..1741cf334f 100644 --- a/mail/mail-config.glade +++ b/mail/mail-config.glade @@ -391,7 +391,7 @@ Click "Finish" to save your settings. GtkLabel identity_address_label - + GTK_JUSTIFY_LEFT False 0 @@ -462,46 +462,11 @@ Click "Finish" to save your settings. table2 3 3 - 3 + 4 False 3 3 - - GnomeFileEntry - fileentry_signature - sig-file-gnome-entry - 10 - Signature file: - False - False - - 1 - 2 - 1 - 2 - 0 - 0 - True - False - False - False - True - False - - - - GtkEntry - GnomeEntry:entry - entry_signature - True - True - True - 0 - - - - GtkLabel identity_organization_label @@ -530,17 +495,21 @@ Click "Finish" to save your settings. - GtkCheckButton - check_html_signature - True - - False - True + GtkLabel + label-sig-text + + GTK_JUSTIFY_LEFT + False + 0 + 0.5 + 0 + 0 + option-sig-text 0 1 - 2 - 3 + 1 + 2 0 0 False @@ -552,57 +521,22 @@ Click "Finish" to save your settings. - - GnomeFileEntry - fileentry_html_signature - html-sig-file-gnome-entry - 10 - HTML signature file: - False - False - - 1 - 2 - 2 - 3 - 0 - 0 - True - False - False - False - True - False - - - - GtkEntry - GnomeEntry:entry - entry_html_signature - True - True - True - 0 - - - - GtkLabel - identity_signature_label - + label-sig-html + GTK_JUSTIFY_LEFT False 0 0.5 0 0 - entry_signature + option-sig-html 0 1 - 1 - 2 + 2 + 3 0 0 False @@ -624,7 +558,7 @@ Click "Finish" to save your settings. 1 - 3 + 4 0 1 0 @@ -640,9 +574,53 @@ Click "Finish" to save your settings. GtkButton - button_edit_signature + button-sig-edit-text True - + + GTK_RELIEF_NORMAL + + 3 + 4 + 1 + 2 + 0 + 0 + False + False + False + False + True + False + + + + + GtkButton + button-sig-edit-html + True + + GTK_RELIEF_NORMAL + + 3 + 4 + 2 + 3 + 0 + 0 + False + False + False + False + True + False + + + + + GtkButton + button-sig-new-text + True + GTK_RELIEF_NORMAL 2 @@ -662,9 +640,9 @@ Click "Finish" to save your settings. GtkButton - button_edit_html_signature + button-sig-new-html True - + GTK_RELIEF_NORMAL 2 @@ -681,6 +659,55 @@ Click "Finish" to save your settings. False + + + GtkOptionMenu + option-sig-html + True + None +Same as text +Random + + 0 + + 1 + 2 + 2 + 3 + 0 + 0 + False + False + False + False + True + False + + + + + GtkOptionMenu + option-sig-text + True + None +Random + + 0 + + 1 + 2 + 1 + 2 + 0 + 0 + True + False + False + False + True + False + + @@ -3131,6 +3158,520 @@ Quoted 0 + + GtkTable + table10 + 4 + 2 + False + 0 + 0 + + + GtkScrolledWindow + scrolledwindow3 + 4 + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + 0 + 1 + 0 + 1 + 0 + 0 + True + True + False + False + True + True + + + + GtkCList + clist-sig + List of signatures + True + 1 + 80 + GTK_SELECTION_BROWSE + False + GTK_SHADOW_IN + + + GtkLabel + CList:title + label56 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + + + + + GtkTable + table-sig-advanced + 4 + 90 + False + 3 + 2 + False + 3 + 3 + + 0 + 1 + 2 + 3 + 0 + 0 + True + False + False + False + True + True + + + + GtkLabel + label62 + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + entry-sig-script + + 0 + 1 + 1 + 2 + 0 + 0 + False + False + False + False + True + False + + + + + GnomeFileEntry + file-sig-script + False + sig-script + 10 + False + False + + 1 + 2 + 1 + 2 + 0 + 0 + True + False + False + False + True + False + + + + GtkEntry + GnomeEntry:entry + entry-sig-script + Script which is run before signature loading from specified filename + True + True + True + 0 + + + + + + GnomeFileEntry + file-sig-filename + False + sig-filename + 10 + False + False + + 1 + 2 + 0 + 1 + 0 + 0 + True + False + False + False + True + False + + + + GtkEntry + GnomeEntry:entry + entry-sig-filename + File containing signature + True + True + True + 0 + /home/rodo/cvs/evolution/mail/ + + + + + GtkLabel + label63 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + entry-sig-filename + + 0 + 1 + 0 + 1 + 0 + 0 + False + False + False + False + True + False + + + + + GtkCheckButton + check-sig-random + False + If selected signature will be included in random signature list + True + + False + True + + 0 + 2 + 2 + 3 + 0 + 0 + False + False + False + False + True + False + + + + + + GtkTable + table9 + 4 + 2 + 2 + False + 3 + 3 + + 0 + 1 + 1 + 2 + 0 + 0 + True + False + False + False + True + False + + + + GtkLabel + label57 + + GTK_JUSTIFY_CENTER + False + 0 + 0.5 + 0 + 0 + entry-sig-name + + 0 + 1 + 0 + 1 + 0 + 0 + False + False + False + False + True + False + + + + + GtkEntry + entry-sig-name + False + Name of selected signature + True + True + True + 0 + + + 1 + 2 + 0 + 1 + 0 + 0 + True + False + False + False + True + False + + + + + GtkCheckButton + check-sig-html + False + True + + False + True + + 0 + 2 + 1 + 2 + 0 + 0 + False + False + False + False + True + False + + + + + + GtkFrame + frame-sig-preview + 4 + 90 + 0 + GTK_SHADOW_IN + + 0 + 1 + 3 + 4 + 0 + 0 + False + False + False + False + True + True + + + + GtkScrolledWindow + scrolled-sig + GTK_POLICY_AUTOMATIC + GTK_POLICY_AUTOMATIC + GTK_UPDATE_CONTINUOUS + GTK_UPDATE_CONTINUOUS + + + Placeholder + + + + + + GtkVButtonBox + vbuttonbox4 + GTK_BUTTONBOX_START + 0 + 85 + 0 + 7 + 0 + + 1 + 2 + 0 + 1 + 0 + 0 + False + False + False + False + True + True + + + + GtkButton + button-sig-add + Add new signature + True + True + + GTK_RELIEF_NORMAL + + + + GtkButton + button-sig-edit + False + Edit signature content in editor + True + True + + GTK_RELIEF_NORMAL + + + + GtkButton + button-sig-delete + False + Delete selected signature + True + True + + GTK_RELIEF_NORMAL + + + + + GtkVBox + vbbox-sig-level + False + 0 + + 1 + 2 + 1 + 4 + 0 + 0 + False + False + False + False + True + True + + + + GtkButton + button-sig-advanced + Show advanced settings + True + True + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + GtkButton + button-sig-simple + Hide advanced settings + True + True + + GTK_RELIEF_NORMAL + + 0 + False + False + + + + + GtkLabel + label65 + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + GTK_PACK_END + + + + + + + GtkLabel + Notebook:tab + other_config_label + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + GtkVBox vbox64 @@ -3438,7 +3979,7 @@ Quoted GtkLabel Notebook:tab - other_config_label + label55 GTK_JUSTIFY_CENTER False diff --git a/mail/mail-config.h b/mail/mail-config.h index 00065fdfd8..d78aa0c7f2 100644 --- a/mail/mail-config.h +++ b/mail/mail-config.h @@ -31,13 +31,24 @@ extern "C" { #pragma } #endif /* __cplusplus */ +typedef struct { + gint id; + gchar *name; + gchar *filename; + gchar *script; + gboolean random; + gboolean html; +} MailConfigSignature; + typedef struct { char *name; char *address; char *organization; - char *signature; - char *html_signature; - gboolean has_html_signature; + + MailConfigSignature *text_signature; + gboolean text_random; + MailConfigSignature *html_signature; + gboolean html_random; } MailConfigIdentity; typedef struct { @@ -98,6 +109,10 @@ typedef enum { MAIL_CONFIG_NOTIFY_PLAY_SOUND, } MailConfigNewMailNotify; +/* signatures */ +MailConfigSignature *signature_copy (const MailConfigSignature *sig); +void signature_destroy (MailConfigSignature *sig); + /* Identities */ MailConfigIdentity *identity_copy (const MailConfigIdentity *id); void identity_destroy (MailConfigIdentity *id); @@ -238,6 +253,33 @@ gboolean mail_config_check_service (const char *url, CamelProviderType type, GLi gboolean evolution_mail_config_factory_init (void); +GList * mail_config_get_signature_list (void); +gint mail_config_get_signatures_random (void); +MailConfigSignature *mail_config_signature_add (gboolean html); +void mail_config_signature_delete (MailConfigSignature *sig); +void mail_config_signature_write (MailConfigSignature *sig); +void mail_config_signature_set_name (MailConfigSignature *sig, const gchar *name); +void mail_config_signature_set_filename (MailConfigSignature *sig, const gchar *filename); +void mail_config_signature_set_random (MailConfigSignature *sig, gboolean random); + +typedef enum { + MAIL_CONFIG_SIG_EVENT_NAME_CHANGED, + MAIL_CONFIG_SIG_EVENT_RANDOM_ON, + MAIL_CONFIG_SIG_EVENT_RANDOM_OFF, + MAIL_CONFIG_SIG_EVENT_ADDED, + MAIL_CONFIG_SIG_EVENT_DELETED +} MailConfigSigEvent; + +typedef void (*MailConfigSignatureClient)(MailConfigSigEvent, MailConfigSignature *sig, gpointer data); + +void mail_config_signature_register_client (MailConfigSignatureClient client, gpointer data); +void mail_config_signature_unregister_client (MailConfigSignatureClient client, gpointer data); +void mail_config_signature_emit_event (MailConfigSigEvent event, MailConfigSignature *sig); + +void mail_config_write_account_sig (MailConfigAccount *account, gint i); +void mail_config_signature_run_script (gchar *script); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/mail/mail-format.c b/mail/mail-format.c index a6e8748d0b..1cc5a3d851 100644 --- a/mail/mail-format.c +++ b/mail/mail-format.c @@ -31,7 +31,8 @@ #include #include -#include +#include +#include #include #include #include diff --git a/mail/mail-ops.c b/mail/mail-ops.c index f53f78c4cb..be6c2ed8ed 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -30,7 +30,8 @@ /* #include */ #include -#include +#include +#include #include #include #include diff --git a/mail/mail-signature-editor.c b/mail/mail-signature-editor.c new file mode 100644 index 0000000000..4a962bf872 --- /dev/null +++ b/mail/mail-signature-editor.c @@ -0,0 +1,276 @@ +#include +#include + +#include + +#include "e-msg-composer.h" +#include "mail-signature-editor.h" + +/* + * Signature editor + * + */ + +struct _ESignatureEditor { + GtkWidget *win; + GtkWidget *control; + + gchar *filename; + gboolean html; + gboolean has_changed; +}; +typedef struct _ESignatureEditor ESignatureEditor; + +#define E_SIGNATURE_EDITOR(o) ((ESignatureEditor *) o) + +#define DEFAULT_WIDTH 600 +#define DEFAULT_HEIGHT 500 + +enum { REPLY_YES = 0, REPLY_NO, REPLY_CANCEL }; + +static void +destroy_editor (ESignatureEditor *editor) +{ + gtk_widget_destroy (editor->win); + g_free (editor->filename); + g_free (editor); +} + +static void +menu_file_save_error (BonoboUIComponent *uic, CORBA_Environment *ev) { + e_notice (GTK_WINDOW (uic), GNOME_MESSAGE_BOX_ERROR, + _("Could not save signature file.")); + + g_warning ("Exception while saving signature (%s)", + bonobo_exception_get_text (ev)); +} + +static void +menu_file_save_cb (BonoboUIComponent *uic, + void *data, + const char *path) +{ + ESignatureEditor *editor; + Bonobo_PersistFile pfile_iface; + CORBA_Environment ev; + + editor = E_SIGNATURE_EDITOR (data); + if (editor->html) { + CORBA_exception_init (&ev); + + pfile_iface = bonobo_object_client_query_interface (bonobo_widget_get_server (BONOBO_WIDGET (editor->control)), + "IDL:Bonobo/PersistFile:1.0", NULL); + Bonobo_PersistFile_save (pfile_iface, editor->filename, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + menu_file_save_error (uic, &ev); + + CORBA_exception_free (&ev); + } else { + BonoboStream *stream; + CORBA_Environment ev; + Bonobo_PersistStream pstream_iface; + + CORBA_exception_init (&ev); + + stream = bonobo_stream_open (BONOBO_IO_DRIVER_FS, editor->filename, + Bonobo_Storage_WRITE | Bonobo_Storage_CREATE, 0); + + pstream_iface = bonobo_object_client_query_interface + (bonobo_widget_get_server (BONOBO_WIDGET (editor->control)), + "IDL:Bonobo/PersistStream:1.0", NULL); + + Bonobo_PersistStream_save (pstream_iface, + (Bonobo_Stream) bonobo_object_corba_objref (BONOBO_OBJECT (stream)), + "text/plain", &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + menu_file_save_error (uic, &ev); + + CORBA_exception_free (&ev); + bonobo_object_unref (BONOBO_OBJECT (stream)); + } +} + +static void +exit_dialog_cb (int reply, ESignatureEditor *editor) +{ + switch (reply) { + case REPLY_YES: + menu_file_save_cb (NULL, editor, NULL); + destroy_editor (editor); + break; + case REPLY_NO: + destroy_editor (editor); + break; + case REPLY_CANCEL: + default: + } +} + +static void +do_exit (ESignatureEditor *editor) +{ + if (editor->has_changed) { + GtkWidget *dialog; + GtkWidget *label; + gint button; + + dialog = gnome_dialog_new (_("Save signature"), + GNOME_STOCK_BUTTON_YES, /* Save */ + GNOME_STOCK_BUTTON_NO, /* Don't save */ + GNOME_STOCK_BUTTON_CANCEL, /* Cancel */ + NULL); + + label = gtk_label_new (_("This signature has been changed, but hasn't been saved.\n" + "\nDo you wish to save your changes?")); + gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), label, TRUE, TRUE, 0); + gtk_widget_show (label); + gnome_dialog_set_parent (GNOME_DIALOG (dialog), GTK_WINDOW (editor->win)); + gnome_dialog_set_default (GNOME_DIALOG (dialog), 0); + button = gnome_dialog_run_and_close (GNOME_DIALOG (dialog)); + + exit_dialog_cb (button, editor); + } else + destroy_editor (editor); +} + +static int +delete_event_cb (GtkWidget *w, GdkEvent *event, ESignatureEditor *editor) +{ + do_exit (editor); + + return FALSE; +} + +static void +menu_file_close_cb (BonoboUIComponent *uic, gpointer data, const gchar *path) +{ + ESignatureEditor *editor; + + editor = E_SIGNATURE_EDITOR (data); + do_exit (editor); +} + +static void +menu_file_save_close_cb (BonoboUIComponent *uic, gpointer data, const gchar *path) +{ + ESignatureEditor *editor; + + editor = E_SIGNATURE_EDITOR (data); + + menu_file_save_cb (uic, editor, path); + destroy_editor (editor); +} + +static BonoboUIVerb verbs [] = { + + BONOBO_UI_VERB ("FileSave", menu_file_save_cb), + BONOBO_UI_VERB ("FileClose", menu_file_close_cb), + BONOBO_UI_VERB ("FileSaveClose", menu_file_save_close_cb), + + BONOBO_UI_VERB_END +}; + +static void +load_signature (ESignatureEditor *editor) +{ + CORBA_Environment ev; + + if (editor->html) { + Bonobo_PersistFile pfile_iface; + + pfile_iface = bonobo_object_client_query_interface (bonobo_widget_get_server (BONOBO_WIDGET (editor->control)), + "IDL:Bonobo/PersistFile:1.0", NULL); + CORBA_exception_init (&ev); + Bonobo_PersistFile_load (pfile_iface, editor->filename, &ev); + CORBA_exception_free (&ev); + } else { + Bonobo_PersistStream pstream_iface; + BonoboStream *stream; + gchar *data, *html; + + data = e_msg_composer_get_sig_file_content (editor->filename, FALSE); + html = g_strdup_printf ("
\n%s", data);
+		g_free (data);
+		
+		pstream_iface = bonobo_object_client_query_interface
+			(bonobo_widget_get_server (BONOBO_WIDGET (editor->control)),
+			 "IDL:Bonobo/PersistStream:1.0", NULL);
+		CORBA_exception_init (&ev);
+		stream = bonobo_stream_mem_create (html, strlen (html), TRUE, FALSE);
+		
+		if (stream == NULL) {
+			g_warning ("Couldn't create memory stream\n");
+		} else {
+			BonoboObject *stream_object;
+			Bonobo_Stream corba_stream;
+			
+			stream_object = BONOBO_OBJECT (stream);
+			corba_stream = bonobo_object_corba_objref (stream_object);
+			Bonobo_PersistStream_load (pstream_iface, corba_stream,
+						   "text/html", &ev);
+		}
+		
+		Bonobo_Unknown_unref (pstream_iface, &ev);
+		CORBA_Object_release (pstream_iface, &ev);
+		CORBA_exception_free (&ev);
+		bonobo_object_unref (BONOBO_OBJECT (stream));
+		
+		g_free (html);
+	}
+}
+
+void
+mail_signature_editor (const gchar *filename, gboolean html)
+{
+	ESignatureEditor *editor;
+	BonoboUIComponent *component;
+	BonoboUIContainer *container;
+	gchar *title;
+	
+	if (!filename || !*filename)
+		return;
+	
+	editor = g_new0 (ESignatureEditor, 1);
+	
+	editor->html     = html;
+	editor->filename = g_strdup (filename);
+	editor->has_changed = TRUE;
+
+	title       = g_strdup_printf ("Edit %ssignature (%s)", html ? "HTML " : "", filename);
+	editor->win = bonobo_window_new ("e-sig-editor", title);
+	gtk_window_set_default_size (GTK_WINDOW (editor->win), DEFAULT_WIDTH, DEFAULT_HEIGHT);
+	gtk_window_set_policy (GTK_WINDOW (editor->win), FALSE, TRUE, FALSE);
+	gtk_window_set_modal (GTK_WINDOW (editor->win), TRUE);
+	g_free (title);
+	
+	container = bonobo_ui_container_new ();
+	bonobo_ui_container_set_win (container, BONOBO_WINDOW (editor->win));
+	
+	component = bonobo_ui_component_new_default ();
+	bonobo_ui_component_set_container (component, bonobo_object_corba_objref (BONOBO_OBJECT (container)));
+	bonobo_ui_component_add_verb_list_with_data (component, verbs, editor);
+	bonobo_ui_util_set_ui (component, EVOLUTION_DATADIR, "evolution-signature-editor.xml", "evolution-signature-editor");
+	
+	editor->control = bonobo_widget_new_control ("OAFIID:GNOME_GtkHTML_Editor",
+						     bonobo_ui_component_get_container (component));
+	
+	if (editor->control == NULL) {
+		g_warning ("Cannot get 'OAFIID:GNOME_GtkHTML_Editor'.");
+		
+		destroy_editor (editor);
+		return;
+	}
+	
+	load_signature (editor);
+
+	gtk_signal_connect (GTK_OBJECT (editor->win), "delete_event",
+			    GTK_SIGNAL_FUNC (delete_event_cb), editor);
+
+	bonobo_window_set_contents (BONOBO_WINDOW (editor->win), editor->control);
+	bonobo_widget_set_property (BONOBO_WIDGET (editor->control), "FormatHTML", html, NULL);
+	gtk_widget_show (GTK_WIDGET (editor->win));
+	gtk_widget_show (GTK_WIDGET (editor->control));
+	gtk_widget_grab_focus (editor->control);
+}
diff --git a/mail/mail-signature-editor.h b/mail/mail-signature-editor.h
new file mode 100644
index 0000000000..741a066470
--- /dev/null
+++ b/mail/mail-signature-editor.h
@@ -0,0 +1,40 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  Authors:
+ *    Radek Doulik 
+ *
+ *  Copyright 2001, 2002 Ximian, Inc. (www.ximian.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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef MAIL_SIGNATURE_EDITOR_H
+#define MAIL_SIGNATURE_EDITOR_H
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+#include 
+
+void mail_signature_editor (const gchar *filename, gboolean html);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif