2009-06-02 [colin] 3.7.1cvs65
[claws.git] / src / compose.c
index 47151744acfaa7f7bfcc82d3ef2df4866518fa90..d023b0dc3db8aac94f8908a2a17ea73283d9e564 100644 (file)
@@ -282,7 +282,7 @@ static gint compose_queue_sub                       (Compose        *compose,
                                                 gchar          **msgpath,
                                                 gboolean       check_subject,
                                                 gboolean       remove_reedit_target);
-static void compose_add_attachments            (Compose        *compose,
+static int compose_add_attachments             (Compose        *compose,
                                                 MimeInfo       *parent);
 static gchar *compose_get_header               (Compose        *compose);
 
@@ -496,6 +496,8 @@ static gboolean compose_headerentry_changed_cb         (GtkWidget          *entry,
 static gboolean compose_headerentry_key_press_event_cb(GtkWidget              *entry,
                                            GdkEventKey        *event,
                                            ComposeHeaderEntry *headerentry);
+static gboolean compose_headerentry_button_clicked_cb (GtkWidget *button,
+                                       ComposeHeaderEntry *headerentry);
 
 static void compose_show_first_last_header (Compose *compose, gboolean show_first);
 
@@ -1018,9 +1020,20 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                if (mailto && *mailto != '\0') {
                        compose_entries_set(compose, mailto, COMPOSE_TO);
 
-               } else if (item && item->prefs && item->prefs->enable_default_to) {
-                       compose_entry_append(compose, item->prefs->default_to, COMPOSE_TO);
-                       compose_entry_mark_default_to(compose, item->prefs->default_to);
+               } else if (item && item->prefs) {
+                       if (item->prefs->enable_default_bcc) {
+                               compose_entry_append(compose, item->prefs->default_bcc, COMPOSE_BCC);
+                       }
+                       if (item->prefs->enable_default_cc) {
+                               compose_entry_append(compose, item->prefs->default_cc, COMPOSE_CC);
+                       }
+                       if (item->prefs->enable_default_replyto) {
+                               compose_entry_append(compose, item->prefs->default_replyto, COMPOSE_REPLYTO);
+                       }
+                       if (item->prefs->enable_default_to) {
+                               compose_entry_append(compose, item->prefs->default_to, COMPOSE_TO);
+                               compose_entry_mark_default_to(compose, item->prefs->default_to);
+                       }
                }
                if (item && item->ret_rcpt) {
                        cm_toggle_menu_set_active_full(compose->ui_manager, "Menu/Options/RequestRetRcpt", TRUE);
@@ -1111,7 +1124,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                        compose_quote_fmt(compose, dummyinfo,
                                          body_format,
                                          NULL, tmp, FALSE, TRUE,
-                                                 _("New message body format error at line %d."));
+                                                 _("The body of the \"New message\" template has an error at line %d."));
                        compose_attach_from_list(compose, quote_fmt_get_attachments_list(), FALSE);
                        quote_fmt_reset_vartable();
 
@@ -1498,7 +1511,7 @@ static Compose *compose_generic_reply(MsgInfo *msginfo,
 
                buf = quote_fmt_get_buffer();
                if (buf == NULL)
-                       alertpanel_error(_("Message reply From format error."));
+                       alertpanel_error(_("The \"From\" field of the \"Reply\" template contains an invalid email address."));
                else
                        gtk_entry_set_text(GTK_ENTRY(compose->from_name), buf);
                quote_fmt_reset_vartable();
@@ -1545,7 +1558,7 @@ static Compose *compose_generic_reply(MsgInfo *msginfo,
                        qmark = "> ";
                compose_quote_fmt(compose, compose->replyinfo,
                                  body_fmt, qmark, body, FALSE, TRUE,
-                                         _("Message reply format error at line %d."));
+                                         _("The body of the \"Reply\" template has an error at line %d."));
                compose_attach_from_list(compose, quote_fmt_get_attachments_list(), FALSE);
                quote_fmt_reset_vartable();
        }
@@ -1669,7 +1682,7 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
 
                buf = quote_fmt_get_buffer();
                if (buf == NULL)
-                       alertpanel_error(_("Message forward From format error."));
+                       alertpanel_error(_("The \"From\" field of the \"Forward\" template contains an invalid email address."));
                else
                        gtk_entry_set_text(GTK_ENTRY(compose->from_name), buf);
                quote_fmt_reset_vartable();
@@ -1734,7 +1747,7 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
 
                compose_quote_fmt(compose, full_msginfo,
                                  body_fmt, qmark, body, FALSE, TRUE,
-                                         _("Message forward format error at line %d."));
+                                         _("The body of the \"Forward\" template has an error at line %d."));
                compose_attach_from_list(compose, quote_fmt_get_attachments_list(), FALSE);
                quote_fmt_reset_vartable();
                compose_attach_parts(compose, msginfo);
@@ -1858,7 +1871,7 @@ static Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_
 
                        buf = quote_fmt_get_buffer();
                        if (buf == NULL)
-                               alertpanel_error(_("Message forward From format error."));
+                               alertpanel_error(_("The \"From\" field of the \"Forward\" template contains an invalid email address."));
                        else
                                gtk_entry_set_text(GTK_ENTRY(compose->from_name), buf);
                        quote_fmt_reset_vartable();
@@ -2316,7 +2329,7 @@ Compose *compose_redirect(PrefsAccount *account, MsgInfo *msginfo,
        gtk_editable_set_editable(GTK_EDITABLE(compose->subject_entry), FALSE);
 
        compose_quote_fmt(compose, msginfo, "%M", NULL, NULL, FALSE, FALSE,
-                                         _("Message redirect format error at line %d."));
+                                         _("The body of the \"Redirect\" template has an error at line %d."));
        quote_fmt_reset_vartable();
        gtk_text_view_set_editable(GTK_TEXT_VIEW(compose->text), FALSE);
 
@@ -2832,7 +2845,7 @@ static gchar *compose_quote_fmt(Compose *compose, MsgInfo *msginfo,
 
                buf = quote_fmt_get_buffer();
                if (buf == NULL)
-                       alertpanel_error(_("Quote mark format error."));
+                       alertpanel_error(_("The \"Quotation mark\" of the template is invalid."));
                else
                        Xstrdup_a(quote_str, buf, goto error)
        }
@@ -2994,6 +3007,17 @@ static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
                msginfo->folder->prefs->enable_default_reply_to;
 
        if (compose->account->protocol != A_NNTP) {
+               if (msginfo && msginfo->folder && msginfo->folder->prefs) {
+                       if (msginfo->folder->prefs->enable_default_replyto) {
+                               compose_entry_append(compose, msginfo->folder->prefs->default_replyto, COMPOSE_REPLYTO);
+                       }
+                       if (msginfo->folder->prefs->enable_default_bcc) {
+                               compose_entry_append(compose, msginfo->folder->prefs->default_bcc, COMPOSE_BCC);
+                       }
+                       if (msginfo->folder->prefs->enable_default_cc) {
+                               compose_entry_append(compose, msginfo->folder->prefs->default_cc, COMPOSE_CC);
+                       }
+               }
                if (reply_to_ml && !default_reply_to) {
                        
                        gboolean is_subscr = is_subscription(compose->ml_post,
@@ -4096,6 +4120,7 @@ static gboolean compose_beautify_paragraph(Compose *compose, GtkTextIter *par_it
                        {"https://", strcasestr, get_uri_part,   make_uri_string},
                        {"ftp://",   strcasestr, get_uri_part,   make_uri_string},
                        {"sftp://",  strcasestr, get_uri_part,   make_uri_string},
+                       {"gopher://",strcasestr, get_uri_part,   make_uri_string},
                        {"www.",     strcasestr, get_uri_part,   make_http_string},
                        {"mailto:",  strcasestr, get_uri_part,   make_uri_string},
                        {"@",        strcasestr, get_email_part, make_email_string}
@@ -4518,7 +4543,8 @@ compose_current_mail_account(void)
 static void compose_select_account(Compose *compose, PrefsAccount *account,
                                   gboolean init)
 {
-       gchar *from = NULL;
+       gchar *from = NULL, *header;
+       ComposeHeaderEntry *header_entry;
 
        cm_return_if_fail(account != NULL);
 
@@ -4556,7 +4582,26 @@ static void compose_select_account(Compose *compose, PrefsAccount *account,
                compose_insert_sig(compose, TRUE);
                undo_unblock(compose->undostruct);
        }
-
+       
+       header_entry = (ComposeHeaderEntry *) compose->header_list->data;
+       header = gtk_combo_box_get_active_text(GTK_COMBO_BOX(header_entry->combo));
+       
+       if (header && !strlen(gtk_entry_get_text(GTK_ENTRY(header_entry->entry)))) {
+               if (account->protocol == A_NNTP) {
+                       if (!strcmp(header, _("To:")))
+                               combobox_select_by_text(
+                                       GTK_COMBO_BOX(header_entry->combo),
+                                       _("Newsgroups:"));
+               } else {
+                       if (!strcmp(header, _("Newsgroups:")))
+                               combobox_select_by_text(
+                                       GTK_COMBO_BOX(header_entry->combo),
+                                       _("To:"));
+               }
+               
+       }
+       g_free(header);
+       
 #ifdef USE_ENCHANT
        /* use account's dict info if set */
        if (compose->gtkaspell) {
@@ -5315,7 +5360,8 @@ static gint compose_write_to_file(Compose *compose, FILE *fp, gint action, gbool
                g_node_append(mimempart->node, mimetext->node);
                g_node_append(mimemsg->node, mimempart->node);
 
-               compose_add_attachments(compose, mimempart);
+               if (compose_add_attachments(compose, mimempart) < 0)
+                       return -1;
        } else
                g_node_append(mimemsg->node, mimetext->node);
 
@@ -5740,7 +5786,7 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
        return 0;
 }
 
-static void compose_add_attachments(Compose *compose, MimeInfo *parent)
+static int compose_add_attachments(Compose *compose, MimeInfo *parent)
 {
        AttachInfo *ainfo;
        GtkTreeView *tree_view = GTK_TREE_VIEW(compose->attach_clist);
@@ -5753,12 +5799,22 @@ static void compose_add_attachments(Compose *compose, MimeInfo *parent)
        model = gtk_tree_view_get_model(tree_view);
        
        if (!gtk_tree_model_get_iter_first(model, &iter))
-               return;
+               return 0;
        do {
                gtk_tree_model_get(model, &iter,
                                   COL_DATA, &ainfo,
                                   -1);
-                                                          
+               
+               if (!is_file_exist(ainfo->file)) {
+                       gchar *msg = g_strdup_printf(_("Attachment %s doesn't exist anymore. Ignore?"), ainfo->file);
+                       AlertValue val = alertpanel_full(_("Warning"), msg, _("Cancel sending"), _("Ignore attachment"),
+                                     NULL, FALSE, NULL, ALERT_WARNING, G_ALERTDEFAULT);
+                       g_free(msg);
+                       if (val == G_ALERTDEFAULT) {
+                               return -1;
+                       }
+                       continue;
+               }
                mimepart = procmime_mimeinfo_new();
                mimepart->content = MIMECONTENT_FILE;
                mimepart->data.filename = g_strdup(ainfo->file);
@@ -5807,6 +5863,8 @@ static void compose_add_attachments(Compose *compose, MimeInfo *parent)
 
                g_node_append(parent->node, mimepart->node);
        } while (gtk_tree_model_iter_next(model, &iter));
+       
+       return 0;
 }
 
 #define IS_IN_CUSTOM_HEADER(header) \
@@ -6255,6 +6313,8 @@ static void compose_create_header_entry(Compose *compose)
 
        GtkWidget *combo;
        GtkWidget *entry;
+       GtkWidget *button;
+       GtkWidget *hbox;
        gchar **string;
        const gchar *header = NULL;
        ComposeHeaderEntry *headerentry;
@@ -6280,12 +6340,12 @@ static void compose_create_header_entry(Compose *compose)
        gtk_table_attach(GTK_TABLE(compose->header_table), combo, 0, 1,
                        compose->header_nextrow, compose->header_nextrow+1,
                        GTK_SHRINK, GTK_FILL, 0, 0);
-       if (compose->header_last) {     
+       if (compose->header_last && (compose->draft_timeout_tag != -2)) {
                const gchar *last_header_entry = gtk_entry_get_text(
                                GTK_ENTRY(gtk_bin_get_child(GTK_BIN((compose->header_last->combo)))));
                string = headers;
                while (*string != NULL) {
-                       if (!strcmp(*string, last_header_entry))
+                       if (!strcmp(prefs_common_translated_header_name(*string), last_header_entry))
                                standard_header = TRUE;
                        string++;
                }
@@ -6308,12 +6368,22 @@ static void compose_create_header_entry(Compose *compose)
        g_signal_connect_after(G_OBJECT(gtk_bin_get_child(GTK_BIN((combo)))), "grab_focus",
                         G_CALLBACK(compose_grab_focus_cb), compose);
 
-       /* Entry field */
+       /* Entry field with cleanup button */
+       button = gtk_button_new();
+       gtk_button_set_image(GTK_BUTTON(button),
+                        gtk_image_new_from_stock(GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU));
+       gtk_widget_show(button);
+       CLAWS_SET_TIP(button,
+               _("Delete entry contents"));
        entry = gtk_entry_new(); 
        gtk_widget_show(entry);
        CLAWS_SET_TIP(entry,
                _("Use <tab> to autocomplete from addressbook"));
-       gtk_table_attach(GTK_TABLE(compose->header_table), entry, 1, 2,
+       hbox = gtk_hbox_new (FALSE, 0);
+       gtk_widget_show(hbox);
+       gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
+       gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+       gtk_table_attach(GTK_TABLE(compose->header_table), hbox, 1, 2,
                        compose->header_nextrow, compose->header_nextrow+1,
                        GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
 
@@ -6325,6 +6395,10 @@ static void compose_create_header_entry(Compose *compose)
                         headerentry);
        g_signal_connect_after(G_OBJECT(entry), "grab_focus",
                         G_CALLBACK(compose_grab_focus_cb), compose);
+
+       g_signal_connect(G_OBJECT(button), "clicked",
+                        G_CALLBACK(compose_headerentry_button_clicked_cb),
+                        headerentry); 
                         
        /* email dnd */
        gtk_drag_dest_set(entry, GTK_DEST_DEFAULT_ALL, compose_mime_types, 
@@ -6345,6 +6419,8 @@ static void compose_create_header_entry(Compose *compose)
         headerentry->compose = compose;
         headerentry->combo = combo;
         headerentry->entry = entry;
+        headerentry->button = button;
+        headerentry->hbox = hbox;
         headerentry->headernum = compose->header_nextrow;
 
         compose->header_nextrow++;
@@ -6372,6 +6448,8 @@ static void compose_remove_header_entries(Compose *compose)
                        (ComposeHeaderEntry *)list->data;
                gtk_widget_destroy(headerentry->combo);
                gtk_widget_destroy(headerentry->entry);
+               gtk_widget_destroy(headerentry->button);
+               gtk_widget_destroy(headerentry->hbox);
                g_free(headerentry);
        }
        compose->header_last = NULL;
@@ -7816,7 +7894,7 @@ static void compose_template_apply(Compose *compose, Template *tmpl,
        const gchar *qmark;
        gchar *parsed_str = NULL;
        gint cursor_pos = 0;
-       const gchar *err_msg = _("Template body format error at line %d.");
+       const gchar *err_msg = _("The body of the template has an error at line %d.");
        if (!tmpl) return;
 
        /* process the body */
@@ -10334,6 +10412,13 @@ static void compose_toggle_remove_refs_cb(GtkToggleAction *action, gpointer data
                compose->remove_references = FALSE;
 }
 
+static gboolean compose_headerentry_button_clicked_cb (GtkWidget *button,
+                                        ComposeHeaderEntry *headerentry)
+{
+       gtk_entry_set_text(GTK_ENTRY(headerentry->entry), "");
+       return FALSE;
+}
+
 static gboolean compose_headerentry_key_press_event_cb(GtkWidget *entry,
                                            GdkEventKey *event,
                                            ComposeHeaderEntry *headerentry)
@@ -10680,8 +10765,10 @@ static void compose_reply_from_messageview_real(MessageView *msgview, GSList *ms
 
                                tmp_msginfo->folder = orig_msginfo->folder;
                                tmp_msginfo->msgnum = orig_msginfo->msgnum; 
-                               if (orig_msginfo->tags)
+                               if (orig_msginfo->tags) {
                                        tmp_msginfo->tags = g_slist_copy(orig_msginfo->tags);
+                                       tmp_msginfo->folder->tags_dirty = TRUE;
+                               }
                        }
                }
        }