aboutsummaryrefslogtreecommitdiffstats
path: root/composer/e-msg-composer.c
diff options
context:
space:
mode:
Diffstat (limited to 'composer/e-msg-composer.c')
-rw-r--r--composer/e-msg-composer.c882
1 files changed, 262 insertions, 620 deletions
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index 54cbe376ed..b0c3a4079b 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -22,7 +22,6 @@
* Ettore Perazzoli (ettore@ximian.com)
* Jeffrey Stedfast (fejj@ximian.com)
* Miguel de Icaza (miguel@ximian.com)
- * Radek Doulik (rodo@ximian.com)
*
*/
@@ -45,15 +44,7 @@
#include <ctype.h>
#include <stdlib.h>
#include <dirent.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <gal/unicode/gunicode.h>
-#include <gal/util/e-unicode-i18n.h>
#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-exec.h>
#include <libgnomeui/gnome-app.h>
#include <libgnomeui/gnome-uidefs.h>
#include <libgnomeui/gnome-dialog.h>
@@ -72,10 +63,8 @@
#include <gal/widgets/e-gui-utils.h>
#include <gal/widgets/e-scroll-frame.h>
#include <gal/e-text/e-entry.h>
+#include <gal/util/e-unicode-i18n.h>
#include <gtkhtml/gtkhtml.h>
-#include <gtkhtml/htmlselection.h>
-
-/*#include <addressbook/backend/ebook/e-card.h>*/
#include "widgets/misc/e-charset-picker.h"
@@ -102,7 +91,7 @@
#include "Editor.h"
#include "listener.h"
-#define GNOME_GTKHTML_EDITOR_CONTROL_ID "OAFIID:GNOME_GtkHTML_Editor:1.1"
+#define GNOME_GTKHTML_EDITOR_CONTROL_ID "OAFIID:GNOME_GtkHTML_Editor"
#define DEFAULT_WIDTH 600
@@ -111,7 +100,6 @@
enum {
SEND,
POSTPONE,
- SAVE_DRAFT,
LAST_SIGNAL
};
@@ -120,13 +108,11 @@ static guint signals[LAST_SIGNAL] = { 0 };
enum {
DND_TYPE_MESSAGE_RFC822,
DND_TYPE_TEXT_URI_LIST,
- DND_TYPE_TEXT_VCARD,
};
static GtkTargetEntry drop_types[] = {
{ "message/rfc822", 0, DND_TYPE_MESSAGE_RFC822 },
{ "text/uri-list", 0, DND_TYPE_TEXT_URI_LIST },
- { "text/x-vcard", 0, DND_TYPE_TEXT_VCARD },
};
static const int num_drop_types = sizeof (drop_types) / sizeof (drop_types[0]);
@@ -147,7 +133,6 @@ 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);
@@ -326,13 +311,6 @@ build_message (EMsgComposer *composer)
if (composer->persist_stream_interface == CORBA_OBJECT_NIL)
return NULL;
- /* evil kludgy hack for Redirect */
- if (composer->redirect) {
- e_msg_composer_hdrs_to_redirect (hdrs, composer->redirect);
- camel_object_ref (CAMEL_OBJECT (composer->redirect));
- return composer->redirect;
- }
-
new = camel_mime_message_new ();
e_msg_composer_hdrs_to_message (hdrs, new);
for (i = 0; i < composer->extra_hdr_names->len; i++) {
@@ -695,60 +673,58 @@ build_message (EMsgComposer *composer)
return NULL;
}
-
static char *
-get_file_content (EMsgComposer *composer, const char *file_name, gboolean want_html, guint flags, gboolean warn)
+read_file_content (gint fd)
{
- CamelStreamFilter *filtered_stream;
- CamelStreamMem *memstream;
- CamelMimeFilter *html, *charenc;
- CamelStream *stream;
- GByteArray *buffer;
- const char *charset;
- char *content;
- int fd;
+ GByteArray *contents;
+ gchar buf[4096];
+ gint n;
+ gchar *body;
- fd = open (file_name, O_RDONLY | O_CREAT, 0644);
- if (fd == -1) {
- char *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 ("");
+ g_return_val_if_fail (fd > 0, NULL);
+
+ contents = g_byte_array_new ();
+ while ((n = read (fd, buf, 4096)) > 0) {
+ g_byte_array_append (contents, buf, n);
}
+ g_byte_array_append (contents, "\0", 1);
- stream = camel_stream_fs_new_with_fd (fd);
- filtered_stream = camel_stream_filter_new_with_stream (stream);
- camel_object_unref (CAMEL_OBJECT (stream));
+ body = (n < 0) ? NULL : (gchar *)contents->data;
+ g_byte_array_free (contents, (n < 0));
+
+ return body;
+}
+
+static char *
+get_file_content (const gchar *file_name, gboolean convert, guint flags)
+{
+ gint fd;
+ char *raw;
+ char *html;
- charset = composer ? composer->charset : mail_config_get_default_charset ();
- charenc = (CamelMimeFilter *) camel_mime_filter_charset_new_convert (charset, "utf-8");
- camel_stream_filter_add (filtered_stream, charenc);
- camel_object_unref (CAMEL_OBJECT (charenc));
+ fd = open (file_name, O_RDONLY | O_CREAT, 0775);
- if (want_html) {
- html = camel_mime_filter_tohtml_new (flags, 0);
- camel_stream_filter_add (filtered_stream, html);
- camel_object_unref (CAMEL_OBJECT (html));
- }
+ raw = read_file_content (fd);
- memstream = (CamelStreamMem *) camel_stream_mem_new ();
- buffer = g_byte_array_new ();
- camel_stream_mem_set_byte_array (memstream, buffer);
+ if (raw == NULL) {
+ 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);
+ close (fd);
+ return g_strdup ("");
+ }
+ close (fd);
- camel_stream_write_to_stream (CAMEL_STREAM (filtered_stream), CAMEL_STREAM (memstream));
- camel_object_unref (CAMEL_OBJECT (filtered_stream));
- camel_object_unref (CAMEL_OBJECT (memstream));
+ html = convert ? e_text_to_html (raw, flags) : raw;
- g_byte_array_append (buffer, "", 1);
- content = buffer->data;
- g_byte_array_free (buffer, FALSE);
+ if (convert)
+ g_free (raw);
- return content;
+ return html;
}
char *
@@ -758,7 +734,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, FALSE);
+ return get_file_content (sigfile, !in_html, 0);
}
static void
@@ -780,11 +756,10 @@ 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;
@@ -811,47 +786,26 @@ static gchar *
get_signature_html (EMsgComposer *composer)
{
gboolean format_html = FALSE;
- char *text, *html = NULL, *sig_file = NULL, *script = NULL;
- static gboolean random_initialized = FALSE;
-
- 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 --;
- }
- }
+ gchar *text, *html = NULL, *sig_file = NULL;
+
+ 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 (!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,
@@ -885,7 +839,7 @@ set_editor_text (EMsgComposer *composer, const char *text)
CORBA_exception_init (&ev);
persist = (Bonobo_PersistStream) bonobo_object_client_query_interface (
bonobo_widget_get_server (editor), "IDL:Bonobo/PersistStream:1.0", &ev);
-
+
g_return_if_fail (persist != CORBA_OBJECT_NIL);
stream = bonobo_stream_mem_create (text, strlen (text),
@@ -1012,6 +966,96 @@ load (EMsgComposer *composer, const char *file_name)
CORBA_exception_free (&ev);
}
+/* Exit dialog. (Displays a "Save composition to 'Drafts' before exiting?" warning before actually exiting.) */
+
+enum { REPLY_YES = 0, REPLY_NO, REPLY_CANCEL };
+
+struct _save_info {
+ EMsgComposer *composer;
+ int quitok;
+};
+
+static void
+save_done (CamelFolder *folder, CamelMimeMessage *msg, CamelMessageInfo *info, int ok, void *data)
+{
+ struct _save_info *si = data;
+
+ if (ok && si->quitok)
+ gtk_widget_destroy (GTK_WIDGET (si->composer));
+ else
+ gtk_object_unref (GTK_OBJECT (si->composer));
+
+ g_free (info);
+ g_free (si);
+}
+
+extern CamelFolder *drafts_folder;
+extern char *default_drafts_folder_uri;
+
+static void
+use_default_drafts_cb (gint reply, gpointer data)
+{
+ CamelFolder **folder = data;
+
+ if (reply == 0)
+ *folder = drafts_folder;
+}
+
+static void
+save_folder (char *uri, CamelFolder *folder, gpointer data)
+{
+ CamelFolder **save = data;
+
+ if (folder) {
+ *save = folder;
+ camel_object_ref (CAMEL_OBJECT (folder));
+ }
+}
+
+static void
+save_draft (EMsgComposer *composer, int quitok)
+{
+ CamelMimeMessage *msg;
+ CamelMessageInfo *info;
+ const MailConfigAccount *account;
+ struct _save_info *si;
+ CamelFolder *folder = NULL;
+
+ account = e_msg_composer_get_preferred_account (composer);
+ if (account && account->drafts_folder_uri &&
+ strcmp (account->drafts_folder_uri, default_drafts_folder_uri) != 0) {
+ int id;
+
+ id = mail_get_folder (account->drafts_folder_uri, 0, save_folder, &folder, mail_thread_new);
+ mail_msg_wait (id);
+
+ if (!folder) {
+ GtkWidget *dialog;
+
+ dialog = gnome_ok_cancel_dialog_parented (_("Unable to open the drafts folder for this account.\n"
+ "Would you like to use the default drafts folder?"),
+ use_default_drafts_cb, &folder, GTK_WINDOW (composer));
+ gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
+ if (!folder)
+ return;
+ }
+ } else
+ folder = drafts_folder;
+
+ msg = e_msg_composer_get_message_draft (composer);
+
+ info = g_new0 (CamelMessageInfo, 1);
+ info->flags = CAMEL_MESSAGE_DRAFT | CAMEL_MESSAGE_SEEN;
+
+ si = g_malloc (sizeof (*si));
+ si->composer = composer;
+ gtk_object_ref (GTK_OBJECT (composer));
+ si->quitok = quitok;
+
+ mail_append_mail (folder, msg, info, save_done, si);
+ camel_object_unref (CAMEL_OBJECT (msg));
+}
+
#define AUTOSAVE_SEED ".evolution-composer.autosave-XXXXXX"
#define AUTOSAVE_INTERVAL 60000
@@ -1224,7 +1268,6 @@ autosave_init_file (EMsgComposer *composer)
}
return FALSE;
}
-
static void
autosave_manager_start (AutosaveManager *am)
{
@@ -1298,20 +1341,17 @@ autosave_manager_unregister (AutosaveManager *am, EMsgComposer *composer)
static void
menu_file_save_draft_cb (BonoboUIComponent *uic, void *data, const char *path)
{
- gtk_signal_emit (GTK_OBJECT (data), signals[SAVE_DRAFT], FALSE);
+ save_draft (E_MSG_COMPOSER (data), FALSE);
e_msg_composer_unset_changed (E_MSG_COMPOSER (data));
}
-/* Exit dialog. (Displays a "Save composition to 'Drafts' before exiting?" warning before actually exiting.) */
-
-enum { REPLY_YES = 0, REPLY_NO, REPLY_CANCEL };
-
static void
exit_dialog_cb (int reply, EMsgComposer *composer)
{
switch (reply) {
case REPLY_YES:
- gtk_signal_emit (GTK_OBJECT (composer), signals[SAVE_DRAFT], TRUE);
+ /* this has to be done async */
+ save_draft (composer, TRUE);
e_msg_composer_unset_changed (composer);
break;
case REPLY_NO:
@@ -1328,7 +1368,7 @@ do_exit (EMsgComposer *composer)
GtkWidget *dialog;
gint button;
- if (e_msg_composer_is_dirty (composer)) {
+ if (TRUE || e_msg_composer_is_dirty (composer)) {
dialog = gnome_message_box_new (_("This message has not been sent.\n\nDo you wish to save your changes?"),
GNOME_MESSAGE_BOX_QUESTION,
GNOME_STOCK_BUTTON_YES, /* Save */
@@ -1457,7 +1497,7 @@ menu_edit_delete_all_cb (BonoboUIComponent *uic, void *data, const char *path)
composer = E_MSG_COMPOSER (data);
CORBA_exception_init (&ev);
- GNOME_GtkHTML_Editor_Engine_undoBegin (composer->editor_engine, "Delete all but signature", "Undelete all", &ev);
+ GNOME_GtkHTML_Editor_Engine_undo_begin (composer->editor_engine, "Delete all but signature", "Undelete all", &ev);
GNOME_GtkHTML_Editor_Engine_freeze (composer->editor_engine, &ev);
GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "disable-selection", &ev);
GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "text-default-color", &ev);
@@ -1472,7 +1512,7 @@ menu_edit_delete_all_cb (BonoboUIComponent *uic, void *data, const char *path)
e_msg_composer_show_sig_file (composer);
GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "style-normal", &ev);
GNOME_GtkHTML_Editor_Engine_thaw (composer->editor_engine, &ev);
- GNOME_GtkHTML_Editor_Engine_undoEnd (composer->editor_engine, &ev);
+ GNOME_GtkHTML_Editor_Engine_undo_end (composer->editor_engine, &ev);
CORBA_exception_free (&ev);
printf ("delete all\n");
@@ -1512,18 +1552,18 @@ 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, TRUE);
+ html = get_file_content (file_name, TRUE, E_TEXT_TO_HTML_PRE);
if (html == NULL)
return;
CORBA_exception_init (&ev);
GNOME_GtkHTML_Editor_Engine_freeze (composer->editor_engine, &ev);
GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "cursor-position-save", &ev);
- GNOME_GtkHTML_Editor_Engine_undoBegin (composer->editor_engine, "Insert file", "Uninsert file", &ev);
+ GNOME_GtkHTML_Editor_Engine_undo_begin (composer->editor_engine, "Insert file", "Uninsert file", &ev);
if (!GNOME_GtkHTML_Editor_Engine_isParagraphEmpty (composer->editor_engine, &ev))
GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "insert-paragraph", &ev);
GNOME_GtkHTML_Editor_Engine_insertHTML (composer->editor_engine, html, &ev);
- GNOME_GtkHTML_Editor_Engine_undoEnd (composer->editor_engine, &ev);
+ GNOME_GtkHTML_Editor_Engine_undo_end (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);
@@ -1705,153 +1745,6 @@ static EPixmap pixcache [] = {
};
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);
- default:
- ;
- }
- 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 ("<submenu name=\"EditSignaturesSubmenu\" _label=\"Signatures\">\n"
- "<menuitem name=\"SignatureNone\" _label=\"None\" verb=\"SignatureNone\""
- " type=\"radio\" group=\"signatures_group\"/>\n");
- if (mail_config_get_signatures_random ()) {
- g_string_append (str,
- "<separator name=\"SeparatorRandom\"/>\n"
- "<menuitem name=\"SignatureRandom\" _label=\"Random\" verb=\"SignatureRandom\""
- " type=\"radio\" group=\"signatures_group\"/>\n");
- }
-
- list = mail_config_get_signature_list ();
- if (list) {
-
- g_string_append (str, "<separator name=\"SeparatorList\"/>");
-
- for (l = list; l; len ++, l = l->next) {
- line = g_strdup_printf ("<menuitem name=\"Signature%d\" _label=\"%s\""
- " verb=\"Signature%d\" type=\"radio\" group=\"signatures_group\"/>\n",
- len, ((MailConfigSignature *)l->data)->name, len);
- g_string_append (str, line);
- g_free (line);
- }
- }
-
- g_string_append (str,
- "<separator name=\"SeparatorRegenerate\"/>\n"
- "<menuitem name=\"SignatureRegenerate\" _label=\"_Regenerate\""
- " verb=\"SignatureRegenerate\" accel=\"*Ctrl**Shift*G\"/>");
- g_string_append (str, "</submenu>\n");
-
- bonobo_ui_component_set_translate (composer->uic, "/menu/Edit/EditMisc/", str->str, NULL);
- bonobo_ui_component_set (composer->uic, "/menu/Edit/EditMisc/", "<separator/>", 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)
{
BonoboUIContainer *container;
@@ -2002,9 +1895,6 @@ 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);
}
@@ -2060,110 +1950,6 @@ hdrs_changed_cb (EMsgComposerHdrs *hdrs,
e_msg_composer_set_changed (composer);
}
-enum {
- UPDATE_AUTO_CC,
- UPDATE_AUTO_BCC,
-};
-
-static void
-update_auto_recipients (EMsgComposerHdrs *hdrs, int mode, const char *auto_addrs)
-{
- EDestination *dest, **destv = NULL;
- CamelInternetAddress *iaddr;
- GList *list, *tail, *node;
- int i, n = 0;
-
- tail = list = NULL;
-
- if (auto_addrs) {
- iaddr = camel_internet_address_new ();
- if (camel_address_decode (CAMEL_ADDRESS (iaddr), auto_addrs) != -1) {
- for (i = 0; i < camel_address_length (CAMEL_ADDRESS (iaddr)); i++) {
- const char *name, *addr;
-
- if (!camel_internet_address_get (iaddr, i, &name, &addr))
- continue;
-
- dest = e_destination_new ();
- e_destination_set_auto_recipient (dest, TRUE);
-
- if (name)
- e_destination_set_name (dest, name);
-
- if (addr)
- e_destination_set_email (dest, addr);
-
- node = g_list_alloc ();
- node->data = dest;
- node->next = NULL;
-
- if (tail) {
- node->prev = tail;
- tail->next = node;
- } else {
- node->prev = NULL;
- list = node;
- }
-
- tail = node;
- n++;
- }
- }
-
- camel_object_unref (CAMEL_OBJECT (iaddr));
- }
-
- switch (mode) {
- case UPDATE_AUTO_CC:
- destv = e_msg_composer_hdrs_get_cc (hdrs);
- break;
- case UPDATE_AUTO_BCC:
- destv = e_msg_composer_hdrs_get_bcc (hdrs);
- break;
- default:
- g_assert_not_reached ();
- }
-
- if (destv) {
- for (i = 0; destv[i]; i++) {
- if (!e_destination_is_auto_recipient (destv[i])) {
- node = g_list_alloc ();
- node->data = e_destination_copy (destv[i]);
- node->next = NULL;
-
- if (tail) {
- node->prev = tail;
- tail->next = node;
- } else {
- node->prev = NULL;
- list = node;
- }
-
- tail = node;
- n++;
- }
- }
-
- e_destination_freev (destv);
- }
-
- destv = e_destination_list_to_vector_sized (list, n);
- g_list_free (list);
-
- switch (mode) {
- case UPDATE_AUTO_CC:
- e_msg_composer_hdrs_set_cc (hdrs, destv);
- break;
- case UPDATE_AUTO_BCC:
- e_msg_composer_hdrs_set_bcc (hdrs, destv);
- break;
- default:
- g_assert_not_reached ();
- }
-
- e_destination_freev (destv);
-}
-
static void
from_changed_cb (EMsgComposerHdrs *hdrs, void *data)
{
@@ -2172,18 +1958,10 @@ from_changed_cb (EMsgComposerHdrs *hdrs, void *data)
composer = E_MSG_COMPOSER (data);
if (hdrs->account) {
- const MailConfigAccount *account = hdrs->account;
-
- e_msg_composer_set_pgp_sign (composer, account->pgp_always_sign);
- e_msg_composer_set_smime_sign (composer, account->smime_always_sign);
- update_auto_recipients (hdrs, UPDATE_AUTO_CC, account->always_cc ? account->cc_addrs : NULL);
- update_auto_recipients (hdrs, UPDATE_AUTO_BCC, account->always_bcc ? account->bcc_addrs : NULL);
- } else {
- update_auto_recipients (hdrs, UPDATE_AUTO_CC, NULL);
- update_auto_recipients (hdrs, UPDATE_AUTO_BCC, NULL);
+ e_msg_composer_set_pgp_sign (composer, hdrs->account->pgp_always_sign);
+ e_msg_composer_set_smime_sign (composer, hdrs->account->smime_always_sign);
}
-
- set_editor_signature (composer);
+
e_msg_composer_show_sig_file (composer);
}
@@ -2210,8 +1988,6 @@ destroy (GtkObject *object)
composer = E_MSG_COMPOSER (object);
- mail_config_signature_unregister_client ((MailConfigSignatureClient) sig_event_client, composer);
-
CORBA_exception_init (&ev);
if (composer->config_db) {
@@ -2270,9 +2046,6 @@ destroy (GtkObject *object)
CORBA_exception_free (&ev);
- if (composer->redirect)
- camel_object_unref (CAMEL_OBJECT (composer->redirect));
-
if (composer->editor_listener)
bonobo_object_unref (composer->editor_listener);
@@ -2335,11 +2108,10 @@ message_rfc822_dnd (EMsgComposer *composer, CamelStream *stream)
static void
drag_data_received (EMsgComposer *composer, GdkDragContext *context,
- int x, int y, GtkSelectionData *selection,
+ gint x, gint y, GtkSelectionData *selection,
guint info, guint time)
{
- char *tmp, *filename, **filenames;
- CamelMimePart *mime_part;
+ gchar *tmp, *filename, **filenames;
CamelStream *stream;
CamelURL *url;
int i;
@@ -2377,35 +2149,11 @@ drag_data_received (EMsgComposer *composer, GdkDragContext *context,
g_free (filenames);
break;
- case DND_TYPE_TEXT_VCARD:
- printf ("dropping a text/x-vcard\n");
- mime_part = camel_mime_part_new ();
- camel_mime_part_set_content (mime_part, selection->data,
- selection->length, "text/x-vcard");
- camel_mime_part_set_disposition (mime_part, "inline");
-
- e_msg_composer_attachment_bar_attach_mime_part
- (E_MSG_COMPOSER_ATTACHMENT_BAR (composer->attachment_bar),
- mime_part);
-
- camel_object_unref (CAMEL_OBJECT (mime_part));
default:
- printf ("dropping an unknown\n");
break;
}
}
-typedef void (*GtkSignal_NONE__NONE_INT) (GtkObject *, int, gpointer);
-
-static void marshal_NONE__NONE_INT (GtkObject *object, GtkSignalFunc func,
- gpointer func_data, GtkArg *args)
-{
- GtkSignal_NONE__NONE_INT rfunc;
-
- rfunc = (GtkSignal_NONE__NONE_INT) func;
- (*rfunc)(object, GTK_VALUE_INT (args[0]), func_data);
-}
-
static void
class_init (EMsgComposerClass *klass)
@@ -2439,14 +2187,6 @@ class_init (EMsgComposerClass *klass)
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
- signals[SAVE_DRAFT] =
- gtk_signal_new ("save-draft",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMsgComposerClass, save_draft),
- marshal_NONE__NONE_INT,
- GTK_TYPE_NONE, 1, GTK_TYPE_INT);
-
gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
}
@@ -2483,8 +2223,6 @@ init (EMsgComposer *composer)
composer->has_changed = FALSE;
- composer->redirect = FALSE;
-
composer->charset = NULL;
composer->enable_autosave = TRUE;
@@ -2754,38 +2492,6 @@ 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:
*
@@ -2802,26 +2508,52 @@ 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;
}
+
+/* FIXME: are there any other headers?? */
+/* This is a list of headers that we DO NOT want to append to the
+ * extra_hdr_* arrays.
+ *
+ * Note: a '*' char can be used for a simple wilcard match.
+ * is_special_header() will use g_strNcasecmp() with the first '*'
+ * char being the end of the match string. If no '*' is present, then
+ * it will be assumed that the header must be an exact match.
+ */
+static char *special_headers[] = {
+ "Subject",
+ "Date",
+ "From",
+ "To",
+ "Cc",
+ "Bcc",
+ "Received",
+ "Message-Id",
+ "X-Evolution*",
+ "Content-*",
+ "MIME-Version",
+ NULL
+};
+
static gboolean
is_special_header (const char *hdr_name)
{
- /* Note: a header is a "special header" if it has any meaning:
- 1. it's not a X-* header or
- 2. it's an X-Evolution* header
- */
- if (g_strncasecmp (hdr_name, "X-", 2))
- return TRUE;
-
- if (!g_strncasecmp (hdr_name, "X-Evolution", 11))
- return TRUE;
+ int i;
- /* we can keep all other X-* headers */
+ for (i = 0; special_headers[i]; i++) {
+ char *p;
+
+ if ((p = strchr (special_headers[i], '*'))) {
+ if (!g_strncasecmp (special_headers[i], hdr_name, p - special_headers[i]))
+ return TRUE;
+ } else {
+ if (!g_strcasecmp (special_headers[i], hdr_name))
+ return TRUE;
+ }
+ }
return FALSE;
}
@@ -2844,7 +2576,7 @@ e_msg_composer_flush_pending_body (EMsgComposer *composer, gboolean apply)
body = gtk_object_get_data (GTK_OBJECT (composer), "body:text");
if (body) {
if (apply)
- set_editor_text (composer, body);
+ e_msg_composer_set_body_text (composer, body);
gtk_object_set_data (GTK_OBJECT (composer), "body:text", NULL);
g_free (body);
@@ -3184,10 +2916,8 @@ 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;
}
@@ -3203,35 +2933,29 @@ disable_editor (EMsgComposer *composer)
bonobo_ui_component_set_prop (composer->uic, "/menu/Insert", "sensitive", "0", NULL);
}
-/**
- * e_msg_composer_new_redirect:
- * @message: The message to use as the source
- *
- * Create a new message composer widget.
- *
- * Return value: A pointer to the newly created widget
- **/
-EMsgComposer *
-e_msg_composer_new_redirect (CamelMimeMessage *message, const char *resent_from)
+#if 0
+static GList *
+add_recipients (GList *list, const char *recips, gboolean decode)
{
- EMsgComposer *composer;
- const char *subject;
-
- g_return_val_if_fail (message != NULL, NULL);
-
- composer = e_msg_composer_new_with_message (message);
- subject = camel_mime_message_get_subject (message);
-
- composer->redirect = message;
- camel_object_ref (CAMEL_OBJECT (message));
-
- e_msg_composer_set_headers (composer, resent_from, NULL, NULL, NULL, subject);
+ int len;
+ char *addr;
- disable_editor (composer);
+ while (*recips) {
+ len = strcspn (recips, ",");
+ if (len) {
+ addr = g_strndup (recips, len);
+ if (decode)
+ camel_url_decode (addr);
+ list = g_list_append (list, addr);
+ }
+ recips += len;
+ if (*recips == ',')
+ recips++;
+ }
- return composer;
+ return list;
}
-
+#endif
static GList *
add_recipients (GList *list, const char *recips, gboolean decode)
@@ -3275,21 +2999,24 @@ e_msg_composer_new_from_url (const char *url_in)
EDestination **tov, **ccv, **bccv;
char *subject = NULL, *body = NULL;
const char *p, *header;
- char *content;
int len, clen;
+ char *url, *content;
+
g_return_val_if_fail (g_strncasecmp (url_in, "mailto:", 7) == 0, NULL);
composer = e_msg_composer_new ();
if (!composer)
return NULL;
-
- /* Parse recipients (everything after ':' until '?' or eos). */
- p = url_in + 7;
+
+ url = g_strdup (url_in);
+ camel_url_decode (url);
+
+ /* Parse recipients (everything after ':' until '?' or eos. */
+ p = url + 7;
len = strcspn (p, "?");
if (len) {
content = g_strndup (p, len);
- camel_url_decode (content);
to = add_recipients (to, content, FALSE);
g_free (content);
}
@@ -3309,29 +3036,21 @@ e_msg_composer_new_from_url (const char *url_in)
p += len + 1;
clen = strcspn (p, "&");
-
content = g_strndup (p, clen);
camel_url_decode (content);
-
- if (!g_strncasecmp (header, "to", len)) {
+
+ if (!g_strncasecmp (header, "to", len))
to = add_recipients (to, content, FALSE);
- } else if (!g_strncasecmp (header, "cc", len)) {
+ else if (!g_strncasecmp (header, "cc", len))
cc = add_recipients (cc, content, FALSE);
- } else if (!g_strncasecmp (header, "bcc", len)) {
+ else if (!g_strncasecmp (header, "bcc", len))
bcc = add_recipients (bcc, content, FALSE);
- } else if (!g_strncasecmp (header, "subject", len)) {
- g_free (subject);
+ else if (!g_strncasecmp (header, "subject", len))
subject = g_strdup (content);
- } else if (!g_strncasecmp (header, "body", len)) {
- g_free (body);
+ else if (!g_strncasecmp (header, "body", len))
body = g_strdup (content);
- } else {
- /* add an arbitrary header */
- e_msg_composer_add_header (composer, header, content);
- }
g_free (content);
-
p += clen;
if (*p == '&') {
p++;
@@ -3340,35 +3059,33 @@ e_msg_composer_new_from_url (const char *url_in)
}
}
}
-
+
tov = e_destination_list_to_vector (to);
ccv = e_destination_list_to_vector (cc);
bccv = e_destination_list_to_vector (bcc);
-
+
g_list_free (to);
g_list_free (cc);
g_list_free (bcc);
-
+
hdrs = E_MSG_COMPOSER_HDRS (composer->hdrs);
-
+
e_msg_composer_hdrs_set_to (hdrs, tov);
e_msg_composer_hdrs_set_cc (hdrs, ccv);
e_msg_composer_hdrs_set_bcc (hdrs, bccv);
-
+
e_destination_freev (tov);
e_destination_freev (ccv);
e_destination_freev (bccv);
-
+
if (subject) {
e_msg_composer_hdrs_set_subject (hdrs, subject);
g_free (subject);
}
if (body) {
- char *htmlbody;
-
- htmlbody = e_text_to_html (body, E_TEXT_TO_HTML_PRE);
- set_editor_text (composer, htmlbody);
+ char *htmlbody = e_text_to_html (body, E_TEXT_TO_HTML_PRE);
+ e_msg_composer_set_body_text (composer, htmlbody);
g_free (htmlbody);
}
@@ -3438,11 +3155,10 @@ e_msg_composer_set_body_text (EMsgComposer *composer, const char *text)
{
g_return_if_fail (E_IS_MSG_COMPOSER (composer));
- set_editor_text (composer, text);
+ printf ("setting as body text:\n-----\n%s\n-----\n", text);
+ fflush (stdout);
- /* set editor text unfortunately kills the signature so we
- have to re-show it */
- e_msg_composer_show_sig_file (composer);
+ set_editor_text (composer, text);
}
@@ -3685,8 +3401,8 @@ delete_old_signature (EMsgComposer *composer)
/* if (!rv)
break; */
GNOME_GtkHTML_Editor_Engine_setParagraphData (composer->editor_engine, "signature", "0", &ev);
- GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "delete-back", &ev);
- }
+ } else
+ GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "insert-paragraph", &ev);
CORBA_exception_free (&ev);
}
@@ -3705,38 +3421,30 @@ 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;
CORBA_exception_init (&ev);
GNOME_GtkHTML_Editor_Engine_freeze (composer->editor_engine, &ev);
GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "cursor-position-save", &ev);
- GNOME_GtkHTML_Editor_Engine_undoBegin (composer->editor_engine, "Set signature", "Reset signature", &ev);
+ GNOME_GtkHTML_Editor_Engine_undo_begin (composer->editor_engine, "Set signature", "Reset signature", &ev);
delete_old_signature (composer);
html = get_signature_html (composer);
if (html) {
if (!GNOME_GtkHTML_Editor_Engine_isParagraphEmpty (composer->editor_engine, &ev))
GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "insert-paragraph", &ev);
- if (!GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "cursor-backward", &ev))
- GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "insert-paragraph", &ev);
- else
- GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "cursor-forward", &ev);
/* printf ("insert %s\n", html); */
GNOME_GtkHTML_Editor_Engine_setParagraphData (composer->editor_engine, "orig", "0", &ev);
GNOME_GtkHTML_Editor_Engine_runCommand (composer->editor_engine, "indent-zero", &ev);
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_undo_end (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");
}
/**
@@ -3773,7 +3481,6 @@ 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);
@@ -4233,13 +3940,12 @@ gboolean
e_msg_composer_is_dirty (EMsgComposer *composer)
{
CORBA_Environment ev;
- gboolean rv;
-
+ gboolean dirty = composer->has_changed;
CORBA_exception_init (&ev);
- rv = composer->has_changed || GNOME_GtkHTML_Editor_Engine_hasUndo (composer->editor_engine, &ev);
- CORBA_exception_free (&ev);
-
- return rv;
+
+ dirty = dirty || Bonobo_PersistStream_isDirty (composer->persist_stream_interface, &ev);
+
+ return dirty;
}
void
@@ -4251,69 +3957,5 @@ e_msg_composer_set_enable_autosave (EMsgComposer *composer, gboolean enabled)
composer->enable_autosave = enabled;
}
-static gchar *
-next_word (const gchar *s, const gchar **sr)
-{
- if (!s || !*s)
- return NULL;
- else {
- const gchar *begin;
- gunichar uc;
- gboolean cited;
-
- do {
- begin = s;
- cited = FALSE;
- uc = g_utf8_get_char (s);
- s = g_utf8_next_char (s);
- } while (!html_selection_spell_word (uc, &cited) && !cited && s);
-
- /* we are at beginning of word */
- if (s && *s) {
- gboolean cited_end;
-
- cited_end = FALSE;
- uc = g_utf8_get_char (s);
-
- /* go to end of word */
- while (html_selection_spell_word (uc, &cited_end) || (!cited && cited_end)) {
- cited_end = FALSE;
- s = g_utf8_next_char (s);
- if (!s)
- break;
- uc = g_utf8_get_char (s);
- }
- *sr = s;
- return s ? g_strndup (begin, s - begin) : g_strdup (begin);
- } else
- return NULL;
- }
-}
-
-void
-e_msg_composer_ignore (EMsgComposer *composer, const gchar *str)
-{
- CORBA_Environment ev;
- gchar *word;
- if (!str)
- return;
-
- CORBA_exception_init (&ev);
- while ((word = next_word (str, &str))) {
- /* printf ("ignore word %s\n", word); */
- GNOME_GtkHTML_Editor_Engine_ignoreWord (composer->editor_engine, word, &ev);
- g_free (word);
- }
- CORBA_exception_free (&ev);
-}
-
-void
-e_msg_composer_drop_editor_undo (EMsgComposer *composer)
-{
- CORBA_Environment ev;
-
- CORBA_exception_init (&ev);
- GNOME_GtkHTML_Editor_Engine_dropUndo (composer->editor_engine, &ev);
- CORBA_exception_free (&ev);
-}
+