sync with sylpheed 0.7.0cvs38
[claws.git] / src / compose.c
index 2bf2660c59dd04b27a7dcc1e9f2ecc48b4d0742f..630158b7bc8bbed7fb6da40cce5037a71c612b40 100644 (file)
 #include "template.h"
 #include "undo.h"
 #include "foldersel.h"
+#include "prefs_actions.h"
 
 #if USE_GPGME
 #  include "rfc2015.h"
@@ -171,7 +172,8 @@ static gchar *compose_parse_references              (const gchar    *ref,
 static gchar *compose_quote_fmt                        (Compose        *compose,
                                                 MsgInfo        *msginfo,
                                                 const gchar    *fmt,
-                                                const gchar    *qmark);
+                                                const gchar    *qmark,
+                                                const gchar    *seltext);
 
 static void compose_reply_set_entry            (Compose        *compose,
                                                 MsgInfo        *msginfo,
@@ -440,7 +442,8 @@ static void compose_attach_parts    (Compose        *compose,
 static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
                                  gboolean to_all,
                                  gboolean ignore_replyto,
-                                 gboolean followup_and_reply_to);
+                                 gboolean followup_and_reply_to,
+                                 const gchar *seltext);
 
 void compose_headerentry_changed_cb       (GtkWidget          *entry,
                                            ComposeHeaderEntry *headerentry);
@@ -450,11 +453,10 @@ void compose_headerentry_key_press_event_cb(GtkWidget            *entry,
 
 static void compose_show_first_last_header (Compose *compose, gboolean show_first);
 
-
 #if USE_PSPELL
 static void compose_check_all             (Compose *compose);
+static void compose_highlight_all         (Compose *compose);
 static void compose_check_backwards       (Compose *compose);
-
 static void compose_check_forwards_go     (Compose *compose);
 #endif
 
@@ -462,7 +464,6 @@ static gboolean compose_send_control_enter (Compose *compose);
 static void text_activated                (GtkWidget   *widget,
                                            Compose     *compose);
 
-
 static GtkItemFactoryEntry compose_popup_entries[] =
 {
        {N_("/_Add..."),        NULL, compose_attach_cb, 0, NULL},
@@ -545,7 +546,7 @@ static GtkItemFactoryEntry compose_entries[] =
                                        COMPOSE_CALL_GTK_STEXT_DELETE_BACKWARD_WORD,
                                        NULL},
        {N_("/_Edit/A_dvanced/Delete a word forward"),
-                                       "<alt>D",
+                                       NULL, /* "<alt>D", */
                                        compose_gtk_stext_action_cb,
                                        COMPOSE_CALL_GTK_STEXT_DELETE_FORWARD_WORD,
                                        NULL},
@@ -554,6 +555,11 @@ static GtkItemFactoryEntry compose_entries[] =
                                        compose_gtk_stext_action_cb,
                                        COMPOSE_CALL_GTK_STEXT_DELETE_LINE,
                                        NULL},
+       {N_("/_Edit/A_dvanced/Delete entire line"),
+                                       NULL,
+                                       compose_gtk_stext_action_cb,
+                                       COMPOSE_CALL_GTK_STEXT_DELETE_LINE_N,
+                                       NULL},
        {N_("/_Edit/A_dvanced/Delete to end of line"),
                                        "<control>K",
                                        compose_gtk_stext_action_cb,
@@ -565,14 +571,22 @@ static GtkItemFactoryEntry compose_entries[] =
        {N_("/_Edit/Wrap all long _lines"),
                                        "<control><alt>L", compose_wrap_line_all, 0, NULL},
        {N_("/_Edit/Edit with e_xternal editor"),
-                                       "<control>X", compose_ext_editor_cb, 0, NULL},
+                                       "<shift><control>X", compose_ext_editor_cb, 0, NULL},
+       {N_("/_Edit/---"),              NULL, NULL, 0, "<Separator>"},
+       {N_("/_Edit/Actio_ns"),         NULL, NULL, 0, "<Branch>"},
 #if USE_PSPELL
        {N_("/_Spelling"),              NULL, NULL, 0, "<Branch>"},
-       {N_("/_Spelling/Check all or selection"),NULL, compose_check_all, 0, NULL},
-       {N_("/_Spelling/Check backwards misspelled word"),      NULL, compose_check_backwards , 0, NULL},
-       {N_("/_Spelling/Forward to next misspelled word"),      NULL, compose_check_forwards_go, 0, NULL},
+       {N_("/_Spelling/_Check all or check selection"),
+                                       NULL, compose_check_all, 0, NULL},
+       {N_("/_Spelling/_Highlight all misspelled words"),
+                                       NULL, compose_highlight_all, 0, NULL},
+       {N_("/_Spelling/Check _backwards misspelled word"),
+                                       NULL, compose_check_backwards , 0, NULL},
+       {N_("/_Spelling/_Forward to next misspelled word"),
+                                       NULL, compose_check_forwards_go, 0, NULL},
        {N_("/_Spelling/---"),          NULL, NULL, 0, "<Separator>"},
-       {N_("/_Spelling/Spelling Configuration"),NULL, NULL, 0, "<Branch>"},
+       {N_("/_Spelling/_Spelling Configuration"),
+                                       NULL, NULL, 0, "<Branch>"},
 #endif
 #if 0 /* NEW COMPOSE GUI */
        {N_("/_View"),                  NULL, NULL, 0, "<Branch>"},
@@ -590,10 +604,11 @@ static GtkItemFactoryEntry compose_entries[] =
        {N_("/_Message"),               NULL, NULL, 0, "<Branch>"},
        {N_("/_Message/_Send"),         "<control>Return",
                                        compose_send_cb, 0, NULL},
-       {N_("/_Message/Send _later"),   "<shift><alt>S",
+       {N_("/_Message/Send _later"),   "<shift><control>S",
                                        compose_send_later_cb,  0, NULL},
+       {N_("/_Message/---"),           NULL, NULL, 0, "<Separator>"},
        {N_("/_Message/Save to _draft folder"),
-                                       "<alt>D", compose_draft_cb, 0, NULL},
+                                       "<shift><control>D", compose_draft_cb, 0, NULL},
        {N_("/_Message/Save and _keep editing"),
                                        "<control>S", compose_draft_cb, 1, NULL},
 #if 0 /* NEW COMPOSE GUI */
@@ -616,7 +631,7 @@ static GtkItemFactoryEntry compose_entries[] =
        {N_("/_Message/_Request Return Receipt"),       NULL, compose_toggle_return_receipt_cb, 0, "<ToggleItem>"},
        {N_("/_Tool"),                  NULL, NULL, 0, "<Branch>"},
        {N_("/_Tool/Show _ruler"),      NULL, compose_toggle_ruler_cb, 0, "<ToggleItem>"},
-       {N_("/_Tool/_Address book"),    "<control><alt>A", compose_address_cb , 0, NULL},
+       {N_("/_Tool/_Address book"),    "<shift><control>A", compose_address_cb , 0, NULL},
        {N_("/_Tool/_Template"),        NULL, NULL, 0, "<Branch>"},
        {N_("/_Help"),                  NULL, NULL, 0, "<Branch>"},
        {N_("/_Help/_About"),           NULL, about_show, 0, NULL}
@@ -651,7 +666,7 @@ Compose *compose_bounce(PrefsAccount *account, MsgInfo *msginfo)
                                   msginfo->subject);
        gtk_editable_set_editable(GTK_EDITABLE(c->subject_entry), FALSE);
 
-       compose_quote_fmt(c, msginfo, "%M", NULL);
+       compose_quote_fmt(c, msginfo, "%M", NULL, NULL);
        gtk_editable_set_editable(GTK_EDITABLE(c->text), FALSE);
 
        ifactory = gtk_item_factory_from_widget(c->popupmenu);
@@ -784,22 +799,26 @@ Compose *compose_new_followup_and_replyto(PrefsAccount *account,
 */
 
 void compose_reply(MsgInfo *msginfo, gboolean quote, gboolean to_all,
-                  gboolean ignore_replyto)
+                  gboolean ignore_replyto, const gchar *seltext)
 {
-       compose_generic_reply(msginfo, quote, to_all, ignore_replyto, FALSE);
+       compose_generic_reply(msginfo, quote, to_all, ignore_replyto, FALSE,
+                             seltext);
 }
 
 void compose_followup_and_reply_to(MsgInfo *msginfo, gboolean quote,
                                   gboolean to_all,
-                                  gboolean ignore_replyto)
+                                  gboolean ignore_replyto,
+                                  const gchar *seltext)
 {
-       compose_generic_reply(msginfo, quote, to_all, ignore_replyto, TRUE);
+       compose_generic_reply(msginfo, quote, to_all, ignore_replyto, TRUE,
+                             seltext);
 }
 
 static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
                                  gboolean to_all,
                                  gboolean ignore_replyto,
-                                 gboolean followup_and_reply_to)
+                                 gboolean followup_and_reply_to,
+                                 const gchar *seltext)
 {
        Compose *compose;
        PrefsAccount *account;
@@ -906,7 +925,7 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
 
                quote_str = compose_quote_fmt(compose, msginfo,
                                              prefs_common.quotefmt,
-                                             qmark);
+                                             qmark, seltext);
        }
 
        if (prefs_common.auto_sig)
@@ -921,7 +940,7 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
        gtk_stext_thaw(text);
        gtk_widget_grab_focus(compose->text);
 
-        if (prefs_common.auto_exteditor)
+       if (prefs_common.auto_exteditor)
                compose_exec_ext_editor(compose);
 }
 
@@ -1147,7 +1166,7 @@ if (msginfo->var && *msginfo->var) { \
 }
 
 Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
-                        gboolean as_attach)
+                        gboolean as_attach, const gchar *seltext)
 {
        Compose *compose;
        /*      PrefsAccount *account; */
@@ -1219,7 +1238,8 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
                        qmark = "> ";
 
                quote_str = compose_quote_fmt(compose, msginfo,
-                                             prefs_common.fw_quotefmt, qmark);
+                                             prefs_common.fw_quotefmt, qmark,
+                                             seltext);
                compose_attach_parts(compose, msginfo);
        }
 
@@ -1689,7 +1709,8 @@ static gchar *compose_parse_references(const gchar *ref, const gchar *msgid)
 }
 
 static gchar *compose_quote_fmt(Compose *compose, MsgInfo *msginfo,
-                               const gchar *fmt, const gchar *qmark)
+                               const gchar *fmt, const gchar *qmark,
+                               const gchar *seltext)
 {
        GtkSText *text = GTK_STEXT(compose->text);
        gchar *quote_str = NULL;
@@ -1698,7 +1719,7 @@ static gchar *compose_quote_fmt(Compose *compose, MsgInfo *msginfo,
        gint len;
 
        if (qmark != NULL) {
-               quote_fmt_init(msginfo, NULL);
+               quote_fmt_init(msginfo, NULL, NULL);
                quote_fmt_scan_string(qmark);
                quote_fmt_parse();
 
@@ -1710,7 +1731,7 @@ static gchar *compose_quote_fmt(Compose *compose, MsgInfo *msginfo,
        }
 
        if (fmt && *fmt != '\0') {
-               quote_fmt_init(msginfo, quote_str);
+               quote_fmt_init(msginfo, quote_str, seltext);
                quote_fmt_scan_string(fmt);
                quote_fmt_parse();
 
@@ -1759,6 +1780,12 @@ static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
                                     ? compose->mailinglist
                                     : msginfo->from ? msginfo->from : ""),
                                     COMPOSE_TO);
+
+       if (compose->replyto && to_all)
+               compose_entry_append
+                       (compose, compose->replyto, COMPOSE_CC);
+
+
        if (compose->account->protocol == A_NNTP) {
                if (ignore_replyto)
                        compose_entry_append
@@ -4277,7 +4304,7 @@ static void compose_savemsg_select_cb(GtkWidget *widget, Compose *compose)
        FolderItem *dest;
        gchar * path;
 
-       dest = foldersel_folder_sel(NULL, NULL);
+       dest = foldersel_folder_sel(NULL, FOLDER_SEL_COPY, NULL);
        if (!dest) return;
 
        path = folder_item_get_identifier(dest);
@@ -4567,6 +4594,8 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
        }
 #endif
 
+       update_compose_actions_menu(ifactory, "/Edit/Actions", compose);
+
        switch (prefs_common.toolbar_style) {
        case TOOLBAR_NONE:
                gtk_widget_hide(handlebox);
@@ -4655,16 +4684,23 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode)
         if (prefs_common.enable_pspell) {
                gtkpspell = gtkpspell_new((const gchar*)prefs_common.dictionary,
                                          conv_get_current_charset_str(),
+                                         prefs_common.misspelled_col,
                                          prefs_common.check_while_typing,
+                                         prefs_common.use_alternate,
                                          GTK_STEXT(text));
                if (!gtkpspell) {
                        alertpanel_error(_("Spell checker could not be started.\n%s"), gtkpspellcheckers->error_message);
-                       gtkpspell_checkers_reset();
+                       gtkpspell_checkers_reset_error();
                } else {
 
                        GtkWidget *menuitem;
 
-                       gtkpspell_set_sug_mode(gtkpspell, prefs_common.pspell_sugmode);
+                       if (!gtkpspell_set_sug_mode(gtkpspell, prefs_common.pspell_sugmode)) {
+                               debug_print(_("Pspell: could not set suggestion mode %s"),
+                                   gtkpspellcheckers->error_message);
+                               gtkpspell_checkers_reset_error();
+                       }
+
                        menuitem = gtk_item_factory_get_item(ifactory, "/Spelling/Spelling Configuration");
                        gtkpspell_populate_submenu(gtkpspell, menuitem);
                        menu_set_sensitive(ifactory, "/Spelling", TRUE);
@@ -5000,7 +5036,7 @@ static void compose_template_apply(Compose *compose, Template *tmpl)
 
                memset(&dummyinfo, 0, sizeof(MsgInfo));
                parsed_str = compose_quote_fmt(compose, &dummyinfo,
-                                              tmpl->value, NULL);
+                                              tmpl->value, NULL, NULL);
        } else {
                if (prefs_common.quotemark && *prefs_common.quotemark)
                        qmark = prefs_common.quotemark;
@@ -5008,7 +5044,7 @@ static void compose_template_apply(Compose *compose, Template *tmpl)
                        qmark = "> ";
 
                parsed_str = compose_quote_fmt(compose, compose->replyinfo,
-                                              tmpl->value, qmark);
+                                              tmpl->value, qmark, NULL);
        }
 
        if (parsed_str && prefs_common.auto_sig)
@@ -5475,7 +5511,7 @@ static gint compose_exec_ext_editor_real(const gchar *file)
                g_snprintf(buf, sizeof(buf), def_cmd, file);
        }
 
-       cmdline = g_strsplit(buf, " ", 1024);
+       cmdline = strsplit_with_quote(buf, " ", 1024);
        execvp(cmdline[0], cmdline);
 
        perror("execvp");
@@ -6647,6 +6683,12 @@ static void compose_check_all(Compose *compose)
                gtkpspell_check_all(compose->gtkpspell);
 }
 
+static void compose_highlight_all(Compose *compose)
+{
+       if (compose->gtkpspell)
+               gtkpspell_highlight_all(compose->gtkpspell);
+}
+
 static void compose_check_backwards(Compose *compose)
 {
        if (compose->gtkpspell)