2008-04-30 [colin] 3.4.0cvs18
[claws.git] / src / compose.c
index ac42bb10a801ee41658dd5e3c0aee1506ffdb223..a2d475211749301e9ede5a7b05d7b96e19d41cc3 100644 (file)
@@ -152,7 +152,6 @@ typedef enum
        COMPOSE_CALL_ADVANCED_ACTION_DELETE_FORWARD_WORD,
        COMPOSE_CALL_ADVANCED_ACTION_DELETE_BACKWARD_WORD,
        COMPOSE_CALL_ADVANCED_ACTION_DELETE_LINE,
-       COMPOSE_CALL_ADVANCED_ACTION_DELETE_LINE_N,
        COMPOSE_CALL_ADVANCED_ACTION_DELETE_TO_LINE_END
 } ComposeCallAdvancedAction;
 
@@ -657,11 +656,6 @@ static GtkItemFactoryEntry compose_entries[] =
                                        compose_advanced_action_cb,
                                        COMPOSE_CALL_ADVANCED_ACTION_DELETE_LINE,
                                        NULL},
-       {N_("/_Edit/A_dvanced/Delete entire line"),
-                                       NULL,
-                                       compose_advanced_action_cb,
-                                       COMPOSE_CALL_ADVANCED_ACTION_DELETE_LINE_N,
-                                       NULL},
        {N_("/_Edit/A_dvanced/Delete to end of line"),
                                        "<control>K",
                                        compose_advanced_action_cb,
@@ -1006,6 +1000,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
        const gchar *body_format = NULL;
        gchar *mailto_from = NULL;
        PrefsAccount *mailto_account = NULL;
+       MsgInfo* dummyinfo = NULL;
 
        /* check if mailto defines a from */
        if (mailto && *mailto != '\0') {
@@ -1033,7 +1028,40 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
        if (mailto_from) {
                gtk_entry_set_text(GTK_ENTRY(compose->from_name), mailto_from);
                g_free(mailto_from);
-       }
+       } else
+               /* override from name according to folder properties */
+               if (item && item->prefs &&
+                       item->prefs->compose_with_format &&
+                       item->prefs->compose_override_from_format &&
+                       *item->prefs->compose_override_from_format != '\0') {
+
+                       gchar *tmp = NULL;
+                       gchar *buf = NULL;
+
+                       dummyinfo = compose_msginfo_new_from_compose(compose);
+
+                       /* decode \-escape sequences in the internal representation of the quote format */
+                       tmp = malloc(strlen(item->prefs->compose_override_from_format)+1);
+                       pref_get_unescaped_pref(tmp, item->prefs->compose_override_from_format);
+
+#ifdef USE_ASPELL
+                       quote_fmt_init(dummyinfo, NULL, NULL, FALSE, compose->account, FALSE,
+                                       compose->gtkaspell);
+#else
+                       quote_fmt_init(dummyinfo, NULL, NULL, FALSE, compose->account, FALSE);
+#endif
+                       quote_fmt_scan_string(tmp);
+                       quote_fmt_parse();
+
+                       buf = quote_fmt_get_buffer();
+                       if (buf == NULL)
+                               alertpanel_error(_("New message From format error."));
+                       else
+                               gtk_entry_set_text(GTK_ENTRY(compose->from_name), buf);
+                       quote_fmt_reset_vartable();
+
+                       g_free(tmp);
+               }
 
        ifactory = gtk_item_factory_from_widget(compose->menubar);
 
@@ -1094,7 +1122,6 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
        }
 
        if (subject_format || body_format) {
-               MsgInfo* dummyinfo = NULL;
 
                if ( subject_format
                         && *subject_format != '\0' )
@@ -1103,7 +1130,8 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                        gchar *tmp = NULL;
                        gchar *buf = NULL;
 
-                       dummyinfo = compose_msginfo_new_from_compose(compose);
+                       if (!dummyinfo)
+                               dummyinfo = compose_msginfo_new_from_compose(compose);
 
                        /* decode \-escape sequences in the internal representation of the quote format */
                        tmp = malloc(strlen(subject_format)+1);
@@ -1139,7 +1167,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                        GtkTextIter start, end;
                        gchar *tmp = NULL;
 
-                       if ( dummyinfo == NULL )
+                       if (!dummyinfo)
                                dummyinfo = compose_msginfo_new_from_compose(compose);
 
                        text = GTK_TEXT_VIEW(compose->text);
@@ -1158,8 +1186,8 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI
                        g_free(tmp);
                }
 
-               procmsg_msginfo_free( dummyinfo );
        }
+       procmsg_msginfo_free( dummyinfo );
 
        if (attach_files) {
                gint i;
@@ -1499,7 +1527,43 @@ static Compose *compose_generic_reply(MsgInfo *msginfo,
                g_free(folderidentifier);
        }
 
-       if (compose_parse_header(compose, msginfo) < 0) return NULL;
+       if (compose_parse_header(compose, msginfo) < 0) {
+               compose->updating = FALSE;
+               compose_destroy(compose);
+               return NULL;
+       }
+
+       /* override from name according to folder properties */
+       if (msginfo->folder && msginfo->folder->prefs &&
+               msginfo->folder->prefs->reply_with_format &&
+               msginfo->folder->prefs->reply_override_from_format &&
+               *msginfo->folder->prefs->reply_override_from_format != '\0') {
+
+               gchar *tmp = NULL;
+               gchar *buf = NULL;
+
+               /* decode \-escape sequences in the internal representation of the quote format */
+               tmp = malloc(strlen(msginfo->folder->prefs->reply_override_from_format)+1);
+               pref_get_unescaped_pref(tmp, msginfo->folder->prefs->reply_override_from_format);
+
+#ifdef USE_ASPELL
+               quote_fmt_init(compose->replyinfo, NULL, NULL, FALSE, compose->account, FALSE,
+                               compose->gtkaspell);
+#else
+               quote_fmt_init(compose->replyinfo, NULL, NULL, FALSE, compose->account, FALSE);
+#endif
+               quote_fmt_scan_string(tmp);
+               quote_fmt_parse();
+
+               buf = quote_fmt_get_buffer();
+               if (buf == NULL)
+                       alertpanel_error(_("Message reply From format error."));
+               else
+                       gtk_entry_set_text(GTK_ENTRY(compose->from_name), buf);
+               quote_fmt_reset_vartable();
+
+               g_free(tmp);
+       }
 
        textview = (GTK_TEXT_VIEW(compose->text));
        textbuf = gtk_text_view_get_buffer(textview);
@@ -1625,6 +1689,45 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo,
                g_free(buf2);
        }
 
+       /* override from name according to folder properties */
+       if (msginfo->folder && msginfo->folder->prefs &&
+               msginfo->folder->prefs->forward_with_format &&
+               msginfo->folder->prefs->forward_override_from_format &&
+               *msginfo->folder->prefs->forward_override_from_format != '\0') {
+
+               gchar *tmp = NULL;
+               gchar *buf = NULL;
+               MsgInfo *full_msginfo = NULL;
+
+               if (!as_attach)
+                       full_msginfo = procmsg_msginfo_get_full_info(msginfo);
+               if (!full_msginfo)
+                       full_msginfo = procmsg_msginfo_copy(msginfo);
+
+               /* decode \-escape sequences in the internal representation of the quote format */
+               tmp = malloc(strlen(msginfo->folder->prefs->forward_override_from_format)+1);
+               pref_get_unescaped_pref(tmp, msginfo->folder->prefs->forward_override_from_format);
+
+#ifdef USE_ASPELL
+               quote_fmt_init(full_msginfo, NULL, NULL, FALSE, compose->account, FALSE,
+                               compose->gtkaspell);
+#else
+               quote_fmt_init(full_msginfo, NULL, NULL, FALSE, compose->account, FALSE);
+#endif
+               quote_fmt_scan_string(tmp);
+               quote_fmt_parse();
+
+               buf = quote_fmt_get_buffer();
+               if (buf == NULL)
+                       alertpanel_error(_("Message forward From format error."));
+               else
+                       gtk_entry_set_text(GTK_ENTRY(compose->from_name), buf);
+               quote_fmt_reset_vartable();
+
+               g_free(tmp);
+               procmsg_msginfo_free(full_msginfo);
+       }
+
        textview = GTK_TEXT_VIEW(compose->text);
        textbuf = gtk_text_view_get_buffer(textview);
        compose_create_tags(textview, compose);
@@ -1763,6 +1866,42 @@ static Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_
 
        compose->updating = TRUE;
 
+       /* override from name according to folder properties */
+       if (msginfo_list->data) {
+               MsgInfo *msginfo = msginfo_list->data;
+
+               if (msginfo->folder && msginfo->folder->prefs &&
+                       msginfo->folder->prefs->forward_with_format &&
+                       msginfo->folder->prefs->forward_override_from_format &&
+                       *msginfo->folder->prefs->forward_override_from_format != '\0') {
+
+                       gchar *tmp = NULL;
+                       gchar *buf = NULL;
+
+                       /* decode \-escape sequences in the internal representation of the quote format */
+                       tmp = malloc(strlen(msginfo->folder->prefs->forward_override_from_format)+1);
+                       pref_get_unescaped_pref(tmp, msginfo->folder->prefs->forward_override_from_format);
+
+#ifdef USE_ASPELL
+                       quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE,
+                                       compose->gtkaspell);
+#else
+                       quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE);
+#endif
+                       quote_fmt_scan_string(tmp);
+                       quote_fmt_parse();
+
+                       buf = quote_fmt_get_buffer();
+                       if (buf == NULL)
+                               alertpanel_error(_("Message forward From format error."));
+                       else
+                               gtk_entry_set_text(GTK_ENTRY(compose->from_name), buf);
+                       quote_fmt_reset_vartable();
+
+                       g_free(tmp);
+               }
+       }
+
        textview = GTK_TEXT_VIEW(compose->text);
        textbuf = gtk_text_view_get_buffer(textview);
        compose_create_tags(textview, compose);
@@ -4678,7 +4817,7 @@ gint compose_send(Compose *compose)
                g_free(msgpath);
        } else {
                val = procmsg_send_message_queue(msgpath, &errstr, folder, msgnum, &queued_removed);
-               g_unlink(msgpath);
+               claws_unlink(msgpath);
                g_free(msgpath);
        }
        if (!discard_window) {
@@ -5234,7 +5373,7 @@ static gint compose_write_body_to_file(Compose *compose, const gchar *file)
                FILE_OP_ERROR(file, "fwrite");
                g_free(chars);
                fclose(fp);
-               g_unlink(file);
+               claws_unlink(file);
                return -1;
        }
 
@@ -5242,7 +5381,7 @@ static gint compose_write_body_to_file(Compose *compose, const gchar *file)
 
        if (fclose(fp) == EOF) {
                FILE_OP_ERROR(file, "fclose");
-               g_unlink(file);
+               claws_unlink(file);
                return -1;
        }
        return 0;
@@ -5445,7 +5584,7 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
                        if (!compose_warn_encryption(compose)) {
                                lock = FALSE;
                                fclose(fp);
-                               g_unlink(tmp);
+                               claws_unlink(tmp);
                                g_free(tmp);
                                return -6;
                        }
@@ -5469,7 +5608,7 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
                                 * key selection */
                                lock = FALSE;
                                fclose(fp);
-                               g_unlink(tmp);
+                               claws_unlink(tmp);
                                g_free(tmp);
                                return -5;
                        }
@@ -5513,7 +5652,7 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
                if (compose_redirect_write_to_file(compose, fp) < 0) {
                        lock = FALSE;
                        fclose(fp);
-                       g_unlink(tmp);
+                       claws_unlink(tmp);
                        g_free(tmp);
                        return -2;
                }
@@ -5522,7 +5661,7 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
                if ((result = compose_write_to_file(compose, fp, COMPOSE_WRITE_FOR_SEND, TRUE)) < 0) {
                        lock = FALSE;
                        fclose(fp);
-                       g_unlink(tmp);
+                       claws_unlink(tmp);
                        g_free(tmp);
                        return result - 1; /* -2 for a generic error, -3 for signing error, -4 for encoding */
                }
@@ -5530,14 +5669,14 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
        if (err == TRUE) {
                g_warning("failed to write queue message\n");
                fclose(fp);
-               g_unlink(tmp);
+               claws_unlink(tmp);
                g_free(tmp);
                lock = FALSE;
                return -2;
        }
        if (fclose(fp) == EOF) {
                FILE_OP_ERROR(tmp, "fclose");
-               g_unlink(tmp);
+               claws_unlink(tmp);
                g_free(tmp);
                lock = FALSE;
                return -2;
@@ -5550,7 +5689,7 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
        }
        if (!queue) {
                g_warning("can't find queue folder\n");
-               g_unlink(tmp);
+               claws_unlink(tmp);
                g_free(tmp);
                lock = FALSE;
                return -1;
@@ -5558,14 +5697,14 @@ static gint compose_queue_sub(Compose *compose, gint *msgnum, FolderItem **item,
        folder_item_scan(queue);
        if ((num = folder_item_add_msg(queue, tmp, NULL, FALSE)) < 0) {
                g_warning("can't queue the message\n");
-               g_unlink(tmp);
+               claws_unlink(tmp);
                g_free(tmp);
                lock = FALSE;
                return -1;
        }
        
        if (msgpath == NULL) {
-               g_unlink(tmp);
+               claws_unlink(tmp);
                g_free(tmp);
        } else
                *msgpath = tmp;
@@ -6407,7 +6546,7 @@ static void compose_savemsg_select_cb(GtkWidget *widget, Compose *compose)
        FolderItem *dest;
        gchar * path;
 
-       dest = foldersel_folder_sel(NULL, FOLDER_SEL_COPY, NULL);
+       dest = foldersel_folder_sel(NULL, FOLDER_SEL_COPY, NULL, FALSE);
        if (!dest) return;
 
        path = folder_item_get_identifier(dest);
@@ -7524,6 +7663,24 @@ static void compose_template_apply_fields(Compose *compose, Template *tmpl)
                msginfo = dummyinfo;
        }
 
+       if (tmpl->from && *tmpl->from != '\0') {
+#ifdef USE_ASPELL
+               quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE,
+                               compose->gtkaspell);
+#else
+               quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE);
+#endif
+               quote_fmt_scan_string(tmpl->from);
+               quote_fmt_parse();
+
+               buf = quote_fmt_get_buffer();
+               if (buf == NULL) {
+                       alertpanel_error(_("Template From format error."));
+               } else {
+                       gtk_entry_set_text(GTK_ENTRY(compose->from_name), buf);
+               }
+       }
+
        if (tmpl->to && *tmpl->to != '\0') {
 #ifdef USE_ASPELL
                quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE,
@@ -8242,11 +8399,11 @@ static gboolean compose_input_cb(GIOChannel *source, GIOCondition condition,
                compose_insert_file(compose, compose->exteditor_file);
                compose_changed_cb(NULL, compose);
 
-               if (g_unlink(compose->exteditor_file) < 0)
+               if (claws_unlink(compose->exteditor_file) < 0)
                        FILE_OP_ERROR(compose->exteditor_file, "unlink");
        } else if (buf[0] == '1') {     /* failed */
                g_warning("Couldn't exec external editor\n");
-               if (g_unlink(compose->exteditor_file) < 0)
+               if (claws_unlink(compose->exteditor_file) < 0)
                        FILE_OP_ERROR(compose->exteditor_file, "unlink");
        } else if (buf[0] == '2') {
                g_warning("Couldn't write to file\n");
@@ -8689,7 +8846,7 @@ gboolean compose_draft (gpointer data, guint action)
        }
        if (msgnum < 0) {
 warn_err:
-               g_unlink(tmp);
+               claws_unlink(tmp);
                g_free(tmp);
                if (action != COMPOSE_AUTO_SAVE) {
                        if (action != COMPOSE_DRAFT_FOR_EXIT)
@@ -8790,7 +8947,7 @@ void compose_clear_exit_drafts(void)
        gchar *filepath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
                                      DRAFTED_AT_EXIT, NULL);
        if (is_file_exist(filepath))
-               g_unlink(filepath);
+               claws_unlink(filepath);
        
        g_free(filepath);
 }
@@ -8936,10 +9093,18 @@ static void compose_close_cb(gpointer data, guint action, GtkWidget *widget)
 #endif
 
        if (compose->modified) {
+               if (!g_mutex_trylock(compose->mutex)) {
+                       /* we don't want to lock the mutex once it's available,
+                        * because as the only other part of compose.c locking
+                        * it is compose_close - which means once unlocked,
+                        * the compose struct will be freed */
+                       debug_print("couldn't lock mutex, probably sending\n");
+                       return;
+               }
                val = alertpanel(_("Discard message"),
                                 _("This message has been modified. Discard it?"),
                                 _("_Discard"), _("_Save to Drafts"), GTK_STOCK_CANCEL);
-
+               g_mutex_unlock(compose->mutex);
                switch (val) {
                case G_ALERTDEFAULT:
                        if (prefs_common.autosave)
@@ -9090,7 +9255,8 @@ static void entry_paste_clipboard(Compose *compose, GtkWidget *entry,
                }
        } else if (GTK_IS_EDITABLE(entry))
                gtk_editable_paste_clipboard (GTK_EDITABLE(entry));
-       
+
+       compose->modified = TRUE;
 }
 
 static void entry_allsel(GtkWidget *entry)
@@ -9418,7 +9584,6 @@ static void textview_delete_line (GtkTextView *text)
        GtkTextBuffer *buffer;
        GtkTextMark *mark;
        GtkTextIter ins, start_iter, end_iter;
-       gboolean found;
 
        g_return_if_fail(GTK_IS_TEXT_VIEW(text));
 
@@ -9430,13 +9595,13 @@ static void textview_delete_line (GtkTextView *text)
        gtk_text_iter_set_line_offset(&start_iter, 0);
 
        end_iter = ins;
-       if (gtk_text_iter_ends_line(&end_iter))
-               found = gtk_text_iter_forward_char(&end_iter);
-       else
-               found = gtk_text_iter_forward_to_line_end(&end_iter);
-
-       if (found)
-               gtk_text_buffer_delete(buffer, &start_iter, &end_iter);
+       if (gtk_text_iter_ends_line(&end_iter)){
+               if (!gtk_text_iter_forward_char(&end_iter))
+                       gtk_text_iter_backward_char(&start_iter);
+       }
+       else 
+               gtk_text_iter_forward_to_line_end(&end_iter);
+       gtk_text_buffer_delete(buffer, &start_iter, &end_iter);
 }
 
 static void textview_delete_to_line_end (GtkTextView *text)
@@ -9444,7 +9609,6 @@ static void textview_delete_to_line_end (GtkTextView *text)
        GtkTextBuffer *buffer;
        GtkTextMark *mark;
        GtkTextIter ins, end_iter;
-       gboolean found;
 
        g_return_if_fail(GTK_IS_TEXT_VIEW(text));
 
@@ -9453,11 +9617,10 @@ static void textview_delete_to_line_end (GtkTextView *text)
        gtk_text_buffer_get_iter_at_mark(buffer, &ins, mark);
        end_iter = ins;
        if (gtk_text_iter_ends_line(&end_iter))
-               found = gtk_text_iter_forward_char(&end_iter);
+               gtk_text_iter_forward_char(&end_iter);
        else
-               found = gtk_text_iter_forward_to_line_end(&end_iter);
-       if (found)
-               gtk_text_buffer_delete(buffer, &ins, &end_iter);
+               gtk_text_iter_forward_to_line_end(&end_iter);
+       gtk_text_buffer_delete(buffer, &ins, &end_iter);
 }
 
 static void compose_advanced_action_cb(Compose *compose,
@@ -9480,7 +9643,6 @@ static void compose_advanced_action_cb(Compose *compose,
                {textview_delete_forward_word},
                {textview_delete_backward_word},
                {textview_delete_line},
-               {NULL}, /* gtk_stext_delete_line_n */
                {textview_delete_to_line_end}
        };
 
@@ -9741,7 +9903,7 @@ static void compose_insert_drag_received_cb (GtkWidget            *widget,
                        str_write_to_file(tmpdata, tmpfile);
                        g_free(tmpdata);  
                        compose_insert_file(compose, tmpfile);
-                       g_unlink(tmpfile);
+                       claws_unlink(tmpfile);
                        g_free(tmpfile);
                        gtk_drag_finish(drag_context, TRUE, FALSE, time);
                        compose_beautify_paragraph(compose, NULL, TRUE);
@@ -9801,7 +9963,7 @@ static void compose_insert_drag_received_cb (GtkWidget            *widget,
                gchar *tmpfile = get_tmp_file();
                str_write_to_file((const gchar *)data->data, tmpfile);
                compose_insert_file(compose, tmpfile);
-               g_unlink(tmpfile);
+               claws_unlink(tmpfile);
                g_free(tmpfile);
                gtk_drag_finish(drag_context, TRUE, FALSE, time);
 #endif