sync with 0.8.11cvs22
[claws.git] / src / compose.c
index cf027720724726721b364a1d4ec8eaeb590b9b25..fabcffa09cf8a48ecd287a71fec0cbd81a78d2e9 100644 (file)
@@ -78,7 +78,7 @@
 #include "procmsg.h"
 #include "menu.h"
 #include "stock_pixmap.h"
-#include "send.h"
+#include "send_message.h"
 #include "imap.h"
 #include "news.h"
 #include "customheader.h"
@@ -196,11 +196,11 @@ static void compose_reply_set_entry               (Compose        *compose,
                                                 followup_and_reply_to);
 static void compose_reedit_set_entry           (Compose        *compose,
                                                 MsgInfo        *msginfo);
-static void compose_insert_sig                 (Compose        *compose);
+static void compose_insert_sig                 (Compose        *compose,
+                                                gboolean        replace);
+static gchar *compose_get_signature_str                (Compose        *compose);
 static void compose_insert_file                        (Compose        *compose,
                                                 const gchar    *file);
-static void compose_insert_command_output      (Compose        *compose,
-                                                const gchar    *cmdline);
 static void compose_attach_append              (Compose        *compose,
                                                 const gchar    *file,
                                                 const gchar    *type,
@@ -213,7 +213,8 @@ static void compose_wrap_line_all_full              (Compose        *compose,
                                                 gboolean        autowrap);
 static void compose_set_title                  (Compose        *compose);
 static void compose_select_account             (Compose        *compose,
-                                                PrefsAccount   *account);
+                                                PrefsAccount   *account,
+                                                gboolean        init);
 
 static PrefsAccount *compose_current_mail_account(void);
 /* static gint compose_send                    (Compose        *compose); */
@@ -325,6 +326,9 @@ static void compose_attach_cb               (gpointer        data,
 static void compose_insert_file_cb     (gpointer        data,
                                         guint           action,
                                         GtkWidget      *widget);
+static void compose_insert_sig_cb      (gpointer        data,
+                                        guint           action,
+                                        GtkWidget      *widget);
 
 static void compose_close_cb           (gpointer        data,
                                         guint           action,
@@ -491,7 +495,7 @@ static GtkItemFactoryEntry compose_entries[] =
        {N_("/_File"),                          NULL, NULL, 0, "<Branch>"},
        {N_("/_File/_Attach file"),             "<control>M", compose_attach_cb,      0, NULL},
        {N_("/_File/_Insert file"),             "<control>I", compose_insert_file_cb, 0, NULL},
-       {N_("/_File/Insert si_gnature"),        "<control>G", compose_insert_sig,     0, NULL},
+       {N_("/_File/Insert si_gnature"),        "<control>G", compose_insert_sig_cb,  0, NULL},
        {N_("/_File/---"),                      NULL, NULL, 0, "<Separator>"},
        {N_("/_File/_Close"),                   "<control>W", compose_close_cb, 0, NULL},
 
@@ -701,7 +705,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
        gtk_stext_freeze(text);
 
        if (account->auto_sig)
-               compose_insert_sig(compose);
+               compose_insert_sig(compose, FALSE);
        gtk_editable_set_position(GTK_EDITABLE(text), 0);
        gtk_stext_set_point(text, 0);
 
@@ -964,7 +968,7 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
        }
 
        if (account->auto_sig)
-               compose_insert_sig(compose);
+               compose_insert_sig(compose, FALSE);
 
        if (quote && prefs_common.linewrap_quote)
                compose_wrap_line_all(compose);
@@ -1074,7 +1078,7 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
                }
 
        if (account->auto_sig)
-               compose_insert_sig(compose);
+               compose_insert_sig(compose, FALSE);
 
        if (prefs_common.linewrap_quote)
                compose_wrap_line_all(compose);
@@ -1153,7 +1157,7 @@ Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_list)
        }
 
        if (account->auto_sig)
-               compose_insert_sig(compose);
+               compose_insert_sig(compose, FALSE);
 
        if (prefs_common.linewrap_quote)
                compose_wrap_line_all(compose);
@@ -1435,7 +1439,7 @@ void compose_toolbar_cb(gint action, gpointer data)
                compose_attach_cb(compose, 0, NULL);
                break;
        case A_SIG:
-               compose_insert_sig(compose);
+               compose_insert_sig(compose, FALSE);
                break;
        case A_EXTEDITOR:
                compose_ext_editor_cb(compose, 0, NULL);
@@ -1486,11 +1490,11 @@ static void compose_entries_set(Compose *compose, const gchar *mailto)
 static gint compose_parse_header(Compose *compose, MsgInfo *msginfo)
 {
        static HeaderEntry hentry[] = {{"Reply-To:",    NULL, TRUE},
-                                      {"Cc:",          NULL, FALSE},
+                                      {"Cc:",          NULL, TRUE},
                                       {"References:",  NULL, FALSE},
-                                      {"Bcc:",         NULL, FALSE},
-                                      {"Newsgroups:",  NULL, FALSE},
-                                      {"Followup-To:", NULL, FALSE},
+                                      {"Bcc:",         NULL, TRUE},
+                                      {"Newsgroups:",  NULL, TRUE},
+                                      {"Followup-To:", NULL, TRUE},
                                       {"List-Post:",   NULL, FALSE},
                                       {"X-Priority:",  NULL, FALSE},
                                       {NULL,           NULL, FALSE}};
@@ -1884,44 +1888,100 @@ static void compose_reedit_set_entry(Compose *compose, MsgInfo *msginfo)
 #undef SET_ENTRY
 #undef SET_ADDRESS
 
-static void compose_insert_sig(Compose *compose)
+static void compose_insert_sig(Compose *compose, gboolean replace)
 {
-       static gchar *default_sigfile;
-       gchar *sigfile = NULL;
+       GtkSText *text = GTK_STEXT(compose->text);
+       gint cur_pos;
 
        g_return_if_fail(compose->account != NULL);
 
+       cur_pos = gtk_editable_get_position(GTK_EDITABLE(text));
+
+       gtk_stext_freeze(text);
+
+       if (replace && compose->sig_str) {
+               gchar *tmp;
+               gint pos;
+               gint len;
+
+               if (compose->account->sig_sep)
+                       tmp = g_strconcat(compose->account->sig_sep, "\n",
+                                         compose->sig_str, NULL);
+               else
+                       tmp = g_strdup(compose->sig_str);
+
+               pos = gtkut_stext_find(text, 0, tmp, TRUE);
+               if (pos != -1) {
+                       gtk_stext_set_point(text, pos);
+                       len = get_wcs_len(tmp);
+                       gtk_stext_forward_delete(text, len);
+               } else {
+                       len = gtk_stext_get_length(text);
+                       gtk_stext_set_point(text, len);
+               }
+
+               g_free(tmp);
+       } else
+               gtk_stext_insert(text, NULL, NULL, NULL, "\n\n", 2);
+
+       if (compose->account->sig_sep) {
+               gtk_stext_insert(text, NULL, NULL, NULL, 
+                                compose->account->sig_sep, -1);
+               gtk_stext_insert(text, NULL, NULL, NULL, "\n", 1);
+       }
+
+       g_free(compose->sig_str);
+       compose->sig_str = compose_get_signature_str(compose);
+
+       gtk_stext_insert(text, NULL, NULL, NULL, compose->sig_str, -1);
+
+       gtk_stext_thaw(text);
+
+       if (cur_pos > gtk_stext_get_length(text))
+               cur_pos = gtk_stext_get_length(text);
+
+       gtk_editable_set_position(GTK_EDITABLE(text), cur_pos);
+       gtk_stext_set_point(text, cur_pos);
+}
+
+static gchar *compose_get_signature_str(Compose *compose)
+{
+       static gchar *default_sigfile;
+       gchar *sig_file = NULL;
+       gchar *sig_str = NULL;
+
+       g_return_val_if_fail(compose->account != NULL, NULL);
+
        if (compose->account->sig_type == SIG_FILE) {
                if (compose->account->sig_path)
-                       sigfile = compose->account->sig_path;
+                       sig_file = compose->account->sig_path;
                else {
                        if (!default_sigfile)
                                default_sigfile = g_strconcat
                                        (get_home_dir(), G_DIR_SEPARATOR_S,
                                         DEFAULT_SIGNATURE, NULL);
-                       sigfile = default_sigfile;
+                       sig_file = default_sigfile;
                }
 
-               if (!is_file_or_fifo_exist(sigfile)) {
-                       g_warning("can't open signature file: %s\n", sigfile);
-                       return;
+               if (!is_file_or_fifo_exist(sig_file)) {
+                       g_warning("can't open signature file: %s\n", sig_file);
+                       return NULL;
                }
        }
 
-       gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL, "\n\n", 2);
-       if (compose->account->sig_sep) {
-               gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL,
-                                compose->account->sig_sep, -1);
-               gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL,
-                               "\n", 1);
-       }
-
        if (compose->account->sig_type == SIG_COMMAND) {
                if (compose->account->sig_path)
-                       compose_insert_command_output
-                               (compose, compose->account->sig_path);
-       } else
-               compose_insert_file(compose, sigfile);
+                       sig_str = get_command_output
+                               (compose->account->sig_path);
+       } else {
+               gchar *tmp;
+
+               tmp = file_read_to_str(sig_file);
+               sig_str = normalize_newlines(tmp);
+               g_free(tmp);
+       }
+
+       return sig_str;
 }
 
 static void compose_insert_file(Compose *compose, const gchar *file)
@@ -1957,38 +2017,6 @@ static void compose_insert_file(Compose *compose, const gchar *file)
        fclose(fp);
 }
 
-static void compose_insert_command_output(Compose *compose,
-                                         const gchar *cmdline)
-{
-       GtkSText *text = GTK_STEXT(compose->text);
-       gchar buf[BUFFSIZE];
-       gint len;
-       FILE *fp;
-
-       g_return_if_fail(cmdline != NULL);
-
-       if ((fp = popen(cmdline, "r")) == NULL) {
-               FILE_OP_ERROR(cmdline, "popen");
-               return;
-       }
-
-       gtk_stext_freeze(text);
-
-       while (fgets(buf, sizeof(buf), fp) != NULL) {
-               strcrchomp(buf);
-               len = strlen(buf);
-               if (len > 0 && buf[len - 1] != '\n') {
-                       while (--len >= 0)
-                               if (buf[len] == '\r') buf[len] = '\n';
-               }
-               gtk_stext_insert(text, NULL, NULL, NULL, buf, -1);
-       }
-
-       gtk_stext_thaw(text);
-
-       pclose(fp);
-}
-
 static void compose_attach_append(Compose *compose, const gchar *file,
                                  const gchar *filename,
                                  const gchar *content_type)
@@ -2767,7 +2795,8 @@ compose_current_mail_account(void)
        return ac;
 }
 
-static void compose_select_account(Compose *compose, PrefsAccount *account)
+static void compose_select_account(Compose *compose, PrefsAccount *account,
+                                  gboolean init)
 {
        GtkWidget *menuitem;
        GtkItemFactory *ifactory;
@@ -2852,6 +2881,9 @@ static void compose_select_account(Compose *compose, PrefsAccount *account)
                                       
        activate_gnupg_mode(compose, account);          
 #endif /* USE_GPGME */
+
+       if (!init && account->auto_sig)
+               compose_insert_sig(compose, TRUE);
 }
 
 gboolean compose_check_for_valid_recipient(Compose *compose) {
@@ -5027,13 +5059,15 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
        compose->to_list        = NULL;
        compose->newsgroup_list = NULL;
 
+       compose->undostruct = undostruct;
+
+       compose->sig_str = NULL;
+
        compose->exteditor_file    = NULL;
        compose->exteditor_pid     = -1;
        compose->exteditor_readdes = -1;
        compose->exteditor_tag     = -1;
 
-       compose->redirect_filename = NULL;
-       compose->undostruct = undostruct;
 #if USE_ASPELL
        menu_set_sensitive(ifactory, "/Spelling", FALSE);
        if (mode != COMPOSE_REDIRECT) {
@@ -5066,7 +5100,7 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
        }
 #endif
 
-       compose_select_account(compose, account);
+       compose_select_account(compose, account, TRUE);
 
 #if USE_ASPELL
         compose->gtkaspell      = gtkaspell;
@@ -5304,7 +5338,7 @@ static void compose_template_apply(Compose *compose, Template *tmpl,
                compose_entry_append(compose, tmpl->bcc, COMPOSE_BCC);
 
        if (replace)
-               gtk_stext_clear(GTK_STEXT(compose->text));
+               gtkut_stext_clear(GTK_STEXT(compose->text));
 
        if ((compose->replyinfo == NULL) && (compose->fwdinfo == NULL)) {
                parsed_str = compose_quote_fmt(compose, NULL, tmpl->value,
@@ -5326,7 +5360,7 @@ static void compose_template_apply(Compose *compose, Template *tmpl,
        }
 
        if (replace && parsed_str && compose->account->auto_sig)
-               compose_insert_sig(compose);
+               compose_insert_sig(compose, FALSE);
 
        if (replace && parsed_str) {
                gtk_editable_set_position(GTK_EDITABLE(compose->text), 0);
@@ -5375,6 +5409,10 @@ static void compose_destroy(Compose *compose)
 
        if (compose->redirect_filename)
                g_free(compose->redirect_filename);
+       if (compose->undostruct)
+               undo_destroy(compose->undostruct);
+
+       g_free(compose->sig_str);
 
        g_free(compose->exteditor_file);
 
@@ -5761,20 +5799,20 @@ static void compose_exec_ext_editor(Compose *compose)
                close(pipe_fds[0]);
 
                if (compose_write_body_to_file(compose, tmp) < 0) {
-                       fd_write(pipe_fds[1], "2\n", 2);
+                       fd_write_all(pipe_fds[1], "2\n", 2);
                        _exit(1);
                }
 
                pid_ed = compose_exec_ext_editor_real(tmp);
                if (pid_ed < 0) {
-                       fd_write(pipe_fds[1], "1\n", 2);
+                       fd_write_all(pipe_fds[1], "1\n", 2);
                        _exit(1);
                }
 
                /* wait until editor is terminated */
                waitpid(pid_ed, NULL, 0);
 
-               fd_write(pipe_fds[1], "0\n", 2);
+               fd_write_all(pipe_fds[1], "0\n", 2);
 
                close(pipe_fds[1]);
                _exit(0);
@@ -6075,7 +6113,7 @@ static void account_activated(GtkMenuItem *menuitem, gpointer data)
        g_return_if_fail(ac != NULL);
 
        if (ac != compose->account)
-               compose_select_account(compose, ac);
+               compose_select_account(compose, ac, FALSE);
 }
 
 static void attach_selected(GtkCList *clist, gint row, gint column,
@@ -6294,6 +6332,14 @@ static void compose_insert_file_cb(gpointer data, guint action,
        }
 }
 
+static void compose_insert_sig_cb(gpointer data, guint action,
+                                 GtkWidget *widget)
+{
+       Compose *compose = (Compose *)data;
+
+       compose_insert_sig(compose, FALSE);
+}
+
 static gint compose_delete_cb(GtkWidget *widget, GdkEventAny *event,
                              gpointer data)
 {