toolbar reply refactoring: part 2
[claws.git] / src / compose.c
index 165519e341a1999d6b41994583430bcfb72451b0..743b47ca33a6e2ad3030bd49fc4b892fa421c5dc 100644 (file)
@@ -199,6 +199,8 @@ static void compose_reedit_set_entry                (Compose        *compose,
 static void compose_insert_sig                 (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,
@@ -455,7 +457,7 @@ static void text_inserted           (GtkWidget      *widget,
                                         Compose        *compose);
 static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
                                  gboolean to_all, gboolean to_ml,
-                                 gboolean ignore_replyto,
+                                 gboolean to_sender,
                                  gboolean followup_and_reply_to,
                                  const gchar *body);
 
@@ -698,7 +700,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
        text = GTK_STEXT(compose->text);
        gtk_stext_freeze(text);
 
-       if (prefs_common.auto_sig)
+       if (account->auto_sig)
                compose_insert_sig(compose);
        gtk_editable_set_position(GTK_EDITABLE(text), 0);
        gtk_stext_set_point(text, 0);
@@ -785,26 +787,113 @@ Compose *compose_new_followup_and_replyto(PrefsAccount *account,
 }
 */
 
+void compose_reply_mode(ComposeMode mode, GSList *msginfo_list, gchar *body)
+{
+       MsgInfo *msginfo;
+       guint list_len;
+
+       g_return_if_fail(msginfo_list != NULL);
+
+       msginfo = (MsgInfo*)g_slist_nth_data(msginfo_list, 0);
+       g_return_if_fail(msginfo != NULL);
+
+       list_len = g_slist_length(msginfo_list);
+
+       switch (mode) {
+       case COMPOSE_REPLY:
+               compose_reply(msginfo, prefs_common.reply_with_quote,
+                             FALSE, prefs_common.default_reply_list, FALSE, body);
+               break;
+       case COMPOSE_REPLY_WITH_QUOTE:
+               compose_reply(msginfo, TRUE, FALSE, prefs_common.default_reply_list, FALSE, body);
+               break;
+       case COMPOSE_REPLY_WITHOUT_QUOTE:
+               compose_reply(msginfo, FALSE, FALSE, prefs_common.default_reply_list, FALSE, NULL);
+               break;
+       case COMPOSE_REPLY_TO_SENDER:
+               compose_reply(msginfo, prefs_common.reply_with_quote,
+                             FALSE, FALSE, TRUE, body);
+               break;
+       case COMPOSE_FOLLOWUP_AND_REPLY_TO:
+               compose_followup_and_reply_to(msginfo,
+                                             prefs_common.reply_with_quote,
+                                             FALSE, FALSE, body);
+               break;
+       case COMPOSE_REPLY_TO_SENDER_WITH_QUOTE:
+               compose_reply(msginfo, TRUE, FALSE, FALSE, TRUE, body);
+               break;
+       case COMPOSE_REPLY_TO_SENDER_WITHOUT_QUOTE:
+               compose_reply(msginfo, FALSE, FALSE, FALSE, TRUE, NULL);
+               break;
+       case COMPOSE_REPLY_TO_ALL:
+               compose_reply(msginfo, prefs_common.reply_with_quote,
+                             TRUE, FALSE, FALSE, body);
+               break;
+       case COMPOSE_REPLY_TO_ALL_WITH_QUOTE:
+               compose_reply(msginfo, TRUE, TRUE, FALSE, FALSE, body);
+               break;
+       case COMPOSE_REPLY_TO_ALL_WITHOUT_QUOTE:
+               compose_reply(msginfo, FALSE, TRUE, FALSE, FALSE, NULL);
+               break;
+       case COMPOSE_REPLY_TO_LIST:
+               compose_reply(msginfo, prefs_common.reply_with_quote,
+                             FALSE, TRUE, FALSE, body);
+               break;
+       case COMPOSE_REPLY_TO_LIST_WITH_QUOTE:
+               compose_reply(msginfo, TRUE, FALSE, TRUE, FALSE, body);
+               break;
+       case COMPOSE_REPLY_TO_LIST_WITHOUT_QUOTE:
+               compose_reply(msginfo, FALSE, FALSE, TRUE, FALSE, NULL);
+               break;
+       case COMPOSE_FORWARD:
+               if (prefs_common.forward_as_attachment) {
+                       compose_reply_mode(COMPOSE_FORWARD_AS_ATTACH, msginfo_list, body);
+                       return;
+               } else {
+                       compose_reply_mode(COMPOSE_FORWARD_INLINE, msginfo_list, body);
+                       return;
+               }
+               break;
+       case COMPOSE_FORWARD_INLINE:
+               /* check if we reply to more than one Message */
+               if (list_len == 1) {
+                       compose_forward(NULL, msginfo, FALSE, body);
+                       break;
+               } 
+               /* more messages FALL THROUGH */
+       case COMPOSE_FORWARD_AS_ATTACH:
+               compose_forward_multiple(NULL, msginfo_list);
+               break;
+       case COMPOSE_REDIRECT:
+               compose_redirect(NULL, msginfo);
+               break;
+       default:
+               g_warning("compose_reply(): invalid Compose Mode: %d\n", mode);
+       }
+       
+       //summary_set_marks_selected(summaryview);
+}
+
 void compose_reply(MsgInfo *msginfo, gboolean quote, gboolean to_all,
-                  gboolean to_ml, gboolean ignore_replyto
+                  gboolean to_ml, gboolean to_sender
                   const gchar *body)
 {
        compose_generic_reply(msginfo, quote, to_all, to_ml, 
-                             ignore_replyto, FALSE, body);
+                             to_sender, FALSE, body);
 }
 
 void compose_followup_and_reply_to(MsgInfo *msginfo, gboolean quote,
                                   gboolean to_all,
-                                  gboolean ignore_replyto,
+                                  gboolean to_sender,
                                   const gchar *body)
 {
        compose_generic_reply(msginfo, quote, to_all, FALSE, 
-                             ignore_replyto, TRUE, body);
+                             to_sender, TRUE, body);
 }
 
 static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
                                  gboolean to_all, gboolean to_ml,
-                                 gboolean ignore_replyto,
+                                 gboolean to_sender,
                                  gboolean followup_and_reply_to,
                                  const gchar *body)
 {
@@ -820,7 +909,7 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
        
        g_return_if_fail(account != NULL);
 
-       if (ignore_replyto && account->protocol == A_NNTP &&
+       if (to_sender && account->protocol == A_NNTP &&
            !followup_and_reply_to) {
                reply_account =
                        account_find_from_address(account->address);
@@ -856,7 +945,7 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
 
        if (compose_parse_header(compose, msginfo) < 0) return;
        compose_reply_set_entry(compose, msginfo, to_all, to_ml, 
-                               ignore_replyto, followup_and_reply_to);
+                               to_sender, followup_and_reply_to);
        compose_show_first_last_header(compose, TRUE);
 
        text = GTK_STEXT(compose->text);
@@ -876,7 +965,7 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
                                              qmark, body);
        }
 
-       if (prefs_common.auto_sig)
+       if (account->auto_sig)
                compose_insert_sig(compose);
 
        if (quote && prefs_common.linewrap_quote)
@@ -986,7 +1075,7 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
                        procmsg_msginfo_free(full_msginfo);
                }
 
-       if (prefs_common.auto_sig)
+       if (account->auto_sig)
                compose_insert_sig(compose);
 
        if (prefs_common.linewrap_quote)
@@ -1065,7 +1154,7 @@ Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_list)
                g_free(msgfile);
        }
 
-       if (prefs_common.auto_sig)
+       if (account->auto_sig)
                compose_insert_sig(compose);
 
        if (prefs_common.linewrap_quote)
@@ -1457,6 +1546,7 @@ static gint compose_parse_header(Compose *compose, MsgInfo *msginfo)
                hentry[H_BCC].body = NULL;
        }
        if (hentry[H_NEWSGROUPS].body != NULL) {
+               conv_unmime_header_overwrite(hentry[H_NEWSGROUPS].body);
                compose->newsgroups = hentry[H_NEWSGROUPS].body;
                hentry[H_NEWSGROUPS].body = NULL;
        }
@@ -1628,7 +1718,7 @@ static gchar *compose_quote_fmt(Compose *compose, MsgInfo *msginfo,
 
 static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
                                    gboolean to_all, gboolean to_ml,
-                                   gboolean ignore_replyto,
+                                   gboolean to_sender,
                                    gboolean followup_and_reply_to)
 {
        GSList *cc_list = NULL;
@@ -1640,13 +1730,13 @@ static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
        g_return_if_fail(compose->account != NULL);
        g_return_if_fail(msginfo != NULL);
 
-       if (compose->account->protocol != A_NNTP || followup_and_reply_to) {
+       if (compose->account->protocol != A_NNTP) {
                if (!compose->replyto && to_ml && compose->ml_post
                    && !(msginfo->folder && msginfo->folder->prefs->enable_default_reply_to))
                        compose_entry_append(compose,
                                           compose->ml_post,
                                           COMPOSE_TO);
-               else if (!(to_all || ignore_replyto)
+               else if (!(to_all || to_sender)
                         && msginfo->folder
                         && msginfo->folder->prefs->enable_default_reply_to) {
                        compose_entry_append(compose,
@@ -1654,32 +1744,38 @@ static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
                            COMPOSE_TO);
                } else
                        compose_entry_append(compose,
-                                (compose->replyto && !ignore_replyto)
-                                ? compose->replyto
-                                : msginfo->from ? msginfo->from : "",
-                                COMPOSE_TO);
+                                (compose->replyto && !to_sender)
+                                 ? compose->replyto :
+                                 msginfo->from ? msginfo->from : "",
+                                 COMPOSE_TO);
        } else {
-               if (ignore_replyto)
+               if (to_sender || (compose->followup_to && 
+                       !strncmp(compose->followup_to, "poster", 6)))
                        compose_entry_append
-                               (compose, msginfo->from ? msginfo->from : "",
+                               (compose, 
+                                (compose->replyto ? compose->replyto :
+                                       msginfo->from ? msginfo->from : ""),
                                 COMPOSE_TO);
-               else {
-                       if (compose->followup_to && !strncmp(compose->followup_to, "poster", 6)) {
-                               compose_entry_append
-                                       (compose,
-                                       ((compose->replyto && !ignore_replyto)
-                                       ? compose->replyto
-                                       : msginfo->from ? msginfo->from : ""),
-                                       COMPOSE_TO);                            
-                       } else {
-                               compose_entry_append
-                                       (compose,
-                                        compose->followup_to ? compose->followup_to
-                                        : compose->newsgroups ? compose->newsgroups
-                                        : "",
-                                        COMPOSE_NEWSGROUPS);
-                       }
-               }
+                                
+               else if (followup_and_reply_to || to_all) {
+                       compose_entry_append
+                               (compose,
+                                (compose->replyto ? compose->replyto :
+                                msginfo->from ? msginfo->from : ""),
+                                COMPOSE_TO);                           
+               
+                       compose_entry_append
+                               (compose,
+                                compose->followup_to ? compose->followup_to :
+                                compose->newsgroups ? compose->newsgroups : "",
+                                COMPOSE_NEWSGROUPS);
+               } 
+               else 
+                       compose_entry_append
+                               (compose,
+                                compose->followup_to ? compose->followup_to :
+                                compose->newsgroups ? compose->newsgroups : "",
+                                COMPOSE_NEWSGROUPS);
        }
 
        if (msginfo->subject && *msginfo->subject) {
@@ -1766,6 +1862,8 @@ static void compose_reedit_set_entry(Compose *compose, MsgInfo *msginfo)
        SET_ADDRESS(COMPOSE_CC, compose->cc);
        SET_ADDRESS(COMPOSE_BCC, compose->bcc);
        SET_ADDRESS(COMPOSE_REPLYTO, compose->replyto);
+       SET_ADDRESS(COMPOSE_NEWSGROUPS, compose->newsgroups);
+       SET_ADDRESS(COMPOSE_FOLLOWUPTO, compose->followup_to);
 
        compose_update_priority_menu_item(compose);
 #if USE_GPGME  
@@ -1778,74 +1876,44 @@ static void compose_reedit_set_entry(Compose *compose, MsgInfo *msginfo)
 #undef SET_ENTRY
 #undef SET_ADDRESS
 
-static void compose_exec_sig(Compose *compose, gchar *sigfile)
+static void compose_insert_sig(Compose *compose)
 {
-       FILE  *sigprg;
-       gchar  *buf;
-       size_t buf_len = 128;
-       if (strlen(sigfile) < 2)
-         return;
-       sigprg = popen(sigfile+1, "r");
-       if (sigprg) {
+       static gchar *default_sigfile;
+       gchar *sigfile = NULL;
 
-               buf = g_malloc(buf_len);
-
-               if (!buf) {
-                       gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL, \
-                       "Unable to insert signature (malloc failed)\n", -1);
+       g_return_if_fail(compose->account != NULL);
 
-                       pclose(sigprg);
-                       return;
+       if (compose->account->sig_type == SIG_FILE) {
+               if (compose->account->sig_path)
+                       sigfile = 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;
                }
 
-               while (!feof(sigprg)) {
-                       bzero(buf, buf_len);
-                       fread(buf, buf_len-1, 1, sigprg);
-                       gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL, buf, -1);
+               if (!is_file_or_fifo_exist(sigfile)) {
+                       g_warning("can't open signature file: %s\n", sigfile);
+                       return;
                }
-
-               g_free(buf);
-               pclose(sigprg);
-       }
-       else
-       {
-               gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL, \
-               "Can't exec file: ", -1);
-               gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL, \
-               sigfile+1, -1);
-       }
-}
-
-static void compose_insert_sig(Compose *compose)
-{
-       gchar *sigfile;
-
-       if (compose->account && compose->account->sig_path)
-               sigfile = g_strdup(compose->account->sig_path);
-       else
-               sigfile = g_strconcat(get_home_dir(), G_DIR_SEPARATOR_S,
-                                     DEFAULT_SIGNATURE, NULL);
-
-       if (!is_file_or_fifo_exist(sigfile) && sigfile[0] != '|') {
-               g_free(sigfile);
-               return;
        }
 
        gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL, "\n\n", 2);
-       if (prefs_common.sig_sep) {
+       if (compose->account->sig_sep) {
                gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL,
-                               prefs_common.sig_sep, -1);
+                                compose->account->sig_sep, -1);
                gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL,
                                "\n", 1);
        }
 
-       if (sigfile[0] == '|')
-               compose_exec_sig(compose, sigfile);
-       else
+       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);
-       g_free(sigfile);
 }
 
 static void compose_insert_file(Compose *compose, const gchar *file)
@@ -1881,6 +1949,38 @@ 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)
@@ -2815,6 +2915,11 @@ gint compose_send(Compose *compose)
                alertpanel_error(_("Could not queue message for sending"));
                return -1;
        }
+
+       if (msgnum == 0) {
+               alertpanel_error(_("The message was queued but could not be sent.\nUse \"Send queued messages\" from the main window to retry."));
+               return 0;
+       }
        
        msgpath = folder_item_fetch_msg(folder, msgnum);
        val = procmsg_send_message_queue(msgpath);
@@ -3263,11 +3368,15 @@ static gint compose_write_to_file(Compose *compose, const gchar *file,
                buf = conv_codeset_strdup(chars, src_codeset, out_codeset);
                if (!buf) {
                        AlertValue aval;
+                       gchar *msg;
 
+                       msg = g_strdup_printf(_("Can't convert the character encoding of the message from\n"
+                                               "%s to %s.\n"
+                                               "Send it anyway?"), src_codeset, out_codeset);
                        aval = alertpanel
-                               (_("Error"),
-                                _("Can't convert the character encoding of the message.\n"
-                                  "Send it anyway?"), _("Yes"), _("+No"), NULL);
+                               (_("Error"), msg, _("Yes"), _("+No"), NULL);
+                       g_free(msg);
+
                        if (aval != G_ALERTDEFAULT) {
                                g_free(chars);
                                fclose(fp);
@@ -3715,9 +3824,6 @@ static void compose_write_attach(Compose *compose, FILE *fp)
 
        for (row = 0; (ainfo = gtk_clist_get_row_data(clist, row)) != NULL;
             row++) {
-               gchar buf[BUFFSIZE];
-               gchar inbuf[B64_LINE_SIZE], outbuf[B64_BUFFSIZE];
-
                if ((attach_fp = fopen(ainfo->file, "rb")) == NULL) {
                        g_warning("Can't open file %s\n", ainfo->file);
                        continue;
@@ -4032,7 +4138,8 @@ static gint compose_write_headers(Compose *compose, FILE *fp,
 
        /* Program version and system info */
        /* uname(&utsbuf); */
-       if (g_slist_length(compose->to_list) && !IS_IN_CUSTOM_HEADER("X-Mailer")) {
+       if (g_slist_length(compose->to_list) && !IS_IN_CUSTOM_HEADER("X-Mailer") &&
+           !compose->newsgroup_list) {
                fprintf(fp, "X-Mailer: %s (GTK+ %d.%d.%d; %s)\n",
                        prog_version,
                        gtk_major_version, gtk_minor_version, gtk_micro_version,
@@ -5178,7 +5285,7 @@ static void compose_template_apply(Compose *compose, Template *tmpl,
        if (replace)
                gtk_stext_clear(GTK_STEXT(compose->text));
 
-       if (compose->replyinfo == NULL) {
+       if ((compose->replyinfo == NULL) && (compose->fwdinfo == NULL)) {
                parsed_str = compose_quote_fmt(compose, NULL, tmpl->value,
                                               NULL, NULL);
        } else {
@@ -5187,11 +5294,17 @@ static void compose_template_apply(Compose *compose, Template *tmpl,
                else
                        qmark = "> ";
 
-               parsed_str = compose_quote_fmt(compose, compose->replyinfo,
-                                              tmpl->value, qmark, NULL);
+               if (compose->replyinfo != NULL)
+                       parsed_str = compose_quote_fmt(compose, compose->replyinfo,
+                                                      tmpl->value, qmark, NULL);
+               else if (compose->fwdinfo != NULL)
+                       parsed_str = compose_quote_fmt(compose, compose->fwdinfo,
+                                                      tmpl->value, qmark, NULL);
+               else
+                       parsed_str = NULL;
        }
 
-       if (replace && parsed_str && prefs_common.auto_sig)
+       if (replace && parsed_str && compose->account->auto_sig)
                compose_insert_sig(compose);
 
        if (replace && parsed_str) {