Improve how message body is quoted for reply/forward/etc.
[claws.git] / src / messageview.c
index 1f1f0940e080ee2114455fee194a38fd5aa88afc..4886f08c8e8ab7921d5ab8b5767a5a889588debf 100644 (file)
@@ -67,6 +67,7 @@
 #include "version.h"
 #include "statusbar.h"
 #include "folder_item_prefs.h"
+#include "avatars.h"
 #ifndef USE_NEW_ADDRBOOK
        #include "addressbook.h"
 #else
@@ -365,6 +366,7 @@ static GtkRadioActionEntry msgview_radio_enc_entries[] =
        ENC_ACTION(CS_ISO_8859_9, C_ISO_8859_9, N_("Turkish (ISO-8859-_9)")), /* RADIO set_charset_cb */
        ENC_ACTION("Cyrillic/"CS_ISO_8859_5, C_ISO_8859_5, "ISO-8859-_5"), /* RADIO set_charset_cb */
        ENC_ACTION("Cyrillic/"CS_KOI8_R, C_KOI8_R, "KOI8-_R"), /* RADIO set_charset_cb */
+       ENC_ACTION("Cyrillic/"CS_MACCYR, C_MACCYR, "MAC_CYR"), /* RADIO set_charset_cb */
        ENC_ACTION("Cyrillic/"CS_KOI8_U, C_KOI8_U, "KOI8-_U"), /* RADIO set_charset_cb */
        ENC_ACTION("Cyrillic/"CS_WINDOWS_1251, C_WINDOWS_1251, "Windows-1251"), /* RADIO set_charset_cb */
        ENC_ACTION("Japanese/"CS_ISO_2022_JP, C_ISO_2022_JP, "ISO-2022-_JP"), /* RADIO set_charset_cb */
@@ -441,7 +443,7 @@ MessageView *messageview_create(MainWindow *mainwin)
        return messageview;
 }
 
-GList *messageview_get_msgview_list(void)
+const GList *messageview_get_msgview_list(void)
 {
        return msgview_list;
 }
@@ -571,6 +573,7 @@ static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Encoding", "Cyrillic", "View/Encoding/Cyrillic", GTK_UI_MANAGER_MENU)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Encoding/Cyrillic", CS_ISO_8859_5, "View/Encoding/Cyrillic/"CS_ISO_8859_5, GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Encoding/Cyrillic", CS_KOI8_R, "View/Encoding/Cyrillic/"CS_KOI8_R, GTK_UI_MANAGER_MENUITEM)
+       MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Encoding/Cyrillic", CS_MACCYR, "View/Encoding/Cyrillic/"CS_MACCYR, GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Encoding/Cyrillic", CS_KOI8_U, "View/Encoding/Cyrillic/"CS_KOI8_U, GTK_UI_MANAGER_MENUITEM)
        MENUITEM_ADDUI_MANAGER(msgview->ui_manager, "/Menu/View/Encoding/Cyrillic", CS_WINDOWS_1251, "View/Encoding/Cyrillic/"CS_WINDOWS_1251, GTK_UI_MANAGER_MENUITEM)
 
@@ -835,7 +838,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                ok = strcasecmp(to_addr, buf);
                g_free(to_addr);
        } else {
-               strncpy(buf, _("<No Return-Path found>"), 
+               g_strlcpy(buf, _("<No Return-Path found>"), 
                                sizeof(buf));
        }
        
@@ -1207,11 +1210,12 @@ static void messageview_register_nav(MessageView *messageview)
 }
 
 gboolean messageview_nav_has_prev(MessageView *messageview) {
-       return messageview->trail != NULL &&  messageview->trail_pos > 0;
+       return messageview != NULL && messageview->trail != NULL
+               && messageview->trail_pos > 0;
 }
 
 gboolean messageview_nav_has_next(MessageView *messageview) {
-       if (!messageview->trail)
+       if (!messageview || !messageview->trail)
                return FALSE;
        
        return sc_g_list_bigger(messageview->trail, messageview->trail_pos + 1);
@@ -1274,7 +1278,7 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
 {
        gchar *text = NULL;
        gchar *file;
-       MimeInfo *mimeinfo, *encinfo, *brokeninfo, *root;
+       MimeInfo *mimeinfo, *encinfo, *root;
        gchar *subject = NULL;
        cm_return_val_if_fail(msginfo != NULL, -1);
 
@@ -1378,7 +1382,8 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                messageview_set_menu_sensitive(messageview);
                messageview->msginfo = msginfo;
        }
-       headerview_show(messageview->headerview, messageview->msginfo);
+       if (prefs_common.display_header_pane)
+               headerview_show(messageview->headerview, messageview->msginfo);
 
        messageview_register_nav(messageview);
        messageview_set_position(messageview, 0);
@@ -1428,7 +1433,7 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                return_receipt_show(messageview->noticeview, 
                                    messageview->msginfo);
 
-       if ((brokeninfo = find_broken_part(mimeinfo)) != NULL) {
+       if (find_broken_part(mimeinfo) != NULL) {
                noticeview_set_icon(messageview->noticeview,
                                    STOCK_PIXMAP_NOTICE_WARN);
                if (!noticeview_is_visible(messageview->noticeview)) {
@@ -2114,6 +2119,8 @@ gchar *messageview_get_selection(MessageView *msgview)
        GtkTextView *edit = NULL;
        GtkTextBuffer *textbuf;
        gint body_pos = 0;
+       GtkTextIter start_iter, end_iter;
+       GtkTextMark *body_start, *body_end;
        
        cm_return_val_if_fail(msgview != NULL, NULL);
 
@@ -2135,15 +2142,35 @@ gchar *messageview_get_selection(MessageView *msgview)
 
        textbuf = gtk_text_view_get_buffer(edit);
 
-       if (gtk_text_buffer_get_selection_bounds(textbuf, NULL, NULL))
+       if (gtk_text_buffer_get_selection_bounds(textbuf, NULL, NULL)) {
                return gtkut_text_view_get_selection(edit);
-       else if (msgview->filtered) {
-               GtkTextIter start_iter, end_iter;
-               gtk_text_buffer_get_iter_at_offset(textbuf, &start_iter, body_pos);
-               gtk_text_buffer_get_end_iter(textbuf, &end_iter);
-               gtk_text_buffer_get_text(textbuf, &start_iter, &end_iter, FALSE);
-       } else
-               text = NULL;
+       } else {
+               if (msgview->filtered) {
+                       gtk_text_buffer_get_iter_at_offset(textbuf, &start_iter, body_pos);
+                       gtk_text_buffer_get_end_iter(textbuf, &end_iter);
+               } else {
+                       body_start = gtk_text_buffer_get_mark(textbuf, "body_start");
+
+                       /* If there is no body_start mark, an attachment is likely
+                        * selected, and we're looking at instructions on what to do
+                        * with it. No point in quoting that, so we'll just return NULL,
+                        * so that original message body is quoted instead down the line.
+                        */
+                       if (body_start == NULL) {
+                               return NULL;
+                       }
+
+                       gtk_text_buffer_get_iter_at_mark(textbuf, &start_iter, body_start);
+
+                       body_end = gtk_text_buffer_get_mark(textbuf, "body_end");
+                       if (body_end != NULL) /* Just in case */
+                               gtk_text_buffer_get_iter_at_mark(textbuf, &end_iter, body_end);
+                       else
+                               gtk_text_buffer_get_end_iter(textbuf, &end_iter);
+               }
+
+               return gtk_text_buffer_get_text(textbuf, &start_iter, &end_iter, FALSE);
+       }
 
        return text;
 }
@@ -2187,7 +2214,10 @@ static void print_mimeview(MimeView *mimeview, gint sel_start, gint sel_end, gin
                mainwin = mainwindow_get_mainwindow();
                printing_print(GTK_TEXT_VIEW(mimeview->textview->text),
                               mainwin ? GTK_WINDOW(mainwin->window) : NULL,
-                               sel_start, sel_end);
+                               sel_start, sel_end,
+                               (mimeview->textview->image 
+                                       ? GTK_IMAGE(mimeview->textview->image)
+                                       : NULL));
        }
 }
 
@@ -2579,8 +2609,9 @@ static void parent_cb(GtkAction *action, gpointer data)
 static void goto_unread_folder_cb(GtkAction *action, gpointer data)
 {
        MessageView *messageview = (MessageView *)data;
+
        messageview->updating = TRUE;
-       folderview_select_next_unread(messageview->mainwin->folderview, FALSE);
+       folderview_select_next_with_flag(messageview->mainwin->folderview, MSG_UNREAD, FALSE);
        messageview->updating = FALSE;
 
        if (messageview->deferred_destroy) {
@@ -2823,9 +2854,8 @@ static void add_address_cb(GtkAction *action, gpointer data)
        MessageView *messageview = (MessageView *)data;
        MsgInfo *msginfo, *full_msginfo;
        gchar *from;
-       GtkWidget *image = NULL;
        GdkPixbuf *picture = NULL;
-       gchar *face;
+       AvatarRender *avatarr;
 
        if (!messageview->msginfo || !messageview->msginfo->from) 
                return;
@@ -2836,21 +2866,14 @@ static void add_address_cb(GtkAction *action, gpointer data)
        extract_address(from);
        
        full_msginfo = procmsg_msginfo_get_full_info(msginfo);
-       face = procmsg_msginfo_get_avatar(full_msginfo, AVATAR_FACE);
-       if (face) {
-               image = face_get_from_header(face);
-       }
-#if HAVE_LIBCOMPFACE
-       else {
-               gchar *xface = procmsg_msginfo_get_avatar(full_msginfo, AVATAR_XFACE);
-               if (xface) {
-                       image = xface_get_from_header(xface);
-               }
-       }
-#endif
+
+       avatarr = avatars_avatarrender_new(full_msginfo);
+       hooks_invoke(AVATAR_IMAGE_RENDER_HOOKLIST, avatarr);
+
        procmsg_msginfo_free(full_msginfo);
-       if (image)
-               picture = gtk_image_get_pixbuf(GTK_IMAGE(image));
+
+       if (avatarr->image != NULL)
+               picture = gtk_image_get_pixbuf(GTK_IMAGE(avatarr->image));
 
 #ifndef USE_NEW_ADDRBOOK
        addressbook_add_contact(msginfo->fromname, from, NULL, picture);
@@ -2859,8 +2882,7 @@ static void add_address_cb(GtkAction *action, gpointer data)
                debug_print( "addressbook_add_contact - added\n" );
        }
 #endif
-       if (image)
-               gtk_widget_destroy(image);
+       avatars_avatarrender_free(avatarr);
 }
 
 static void create_filter_cb(GtkAction *gaction, gpointer data)