2007-10-10 [colin] 3.0.2cvs53
[claws.git] / src / textview.c
index cf105704944a126112977982c0ccdf272a31aad7..3cad0d6fc606ea0af6d869248d192dd4b02137ea 100644 (file)
@@ -69,6 +69,7 @@
 #include "inputdialog.h"
 #include "timing.h"
 #include "tags.h"
+#include "addrindex.h"
 
 static GdkColor quote_colors[3] = {
        {(gulong)0, (gushort)0, (gushort)0, (gushort)0},
@@ -99,7 +100,7 @@ static GdkColor emphasis_color = {
        (gulong)0,
        (gushort)0,
        (gushort)0,
-       (gushort)0xcfff
+       (gushort)0
 };
 
 static GdkCursor *hand_cursor = NULL;
@@ -495,7 +496,6 @@ void textview_init(TextView *textview)
 static void textview_update_message_colors(TextView *textview)
 {
        GdkColor black = {0, 0, 0, 0};
-       GdkColor colored_emphasis = {0, 0, 0, 0xcfff};
        GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview->text));
 
        GtkTextTagTable *tags = gtk_text_buffer_get_tag_table(buffer);
@@ -517,7 +517,8 @@ static void textview_update_message_colors(TextView *textview)
                                               &uri_color);
                gtkut_convert_int_to_gdk_color(prefs_common.signature_col,
                                               &signature_color);
-               emphasis_color = colored_emphasis;
+               gtkut_convert_int_to_gdk_color(prefs_common.emphasis_col,
+                                              &emphasis_color);
        }
        if (prefs_common.enable_color && prefs_common.enable_bgcolor) {
                gtkut_convert_int_to_gdk_color(prefs_common.quote_level1_bgcol,
@@ -844,6 +845,8 @@ void textview_show_mime_part(TextView *textview, MimeInfo *partinfo)
        GtkTextView *text;
        GtkTextBuffer *buffer;
        GtkTextIter iter;
+       const gchar *name;
+       gchar *content_type;
 
        if (!partinfo) return;
 
@@ -855,23 +858,57 @@ void textview_show_mime_part(TextView *textview, MimeInfo *partinfo)
        gtk_text_buffer_get_start_iter(buffer, &iter);
 
        TEXTVIEW_INSERT("\n");
-       TEXTVIEW_INSERT(_("  The following can be performed on this part by\n"));
-       TEXTVIEW_INSERT(_("  right-clicking the icon or list item:\n"));
+
+       name = procmime_mimeinfo_get_parameter(partinfo, "filename");
+       if (name == NULL)
+               name = procmime_mimeinfo_get_parameter(partinfo, "name");
+       if (name != NULL) {
+               content_type = procmime_get_content_type_str(partinfo->type,
+                                                    partinfo->subtype);
+               TEXTVIEW_INSERT("  ");
+               TEXTVIEW_INSERT_BOLD(name);
+               TEXTVIEW_INSERT(" (");
+               TEXTVIEW_INSERT(content_type);
+               TEXTVIEW_INSERT(", ");
+               TEXTVIEW_INSERT(to_human_readable(partinfo->length));
+               TEXTVIEW_INSERT("):\n\n");
+               
+               g_free(content_type);
+       }
+       TEXTVIEW_INSERT(_("  The following can be performed on this part\n"));
+#ifndef MAEMO
+       TEXTVIEW_INSERT(_("  by right-clicking the icon or list item:"));
+#endif
+       TEXTVIEW_INSERT("\n");
 
        TEXTVIEW_INSERT(_("     - To save, select "));
        TEXTVIEW_INSERT_LINK(_("'Save as...'"), "sc://save_as", NULL);
-       TEXTVIEW_INSERT(_(" (Shortcut key: 'y')\n"));
+#ifndef MAEMO
+       TEXTVIEW_INSERT(_(" (Shortcut key: 'y')"));
+#endif
+       TEXTVIEW_INSERT("\n");
+
        TEXTVIEW_INSERT(_("     - To display as text, select "));
        TEXTVIEW_INSERT_LINK(_("'Display as text'"), "sc://display_as_text", NULL);
-       TEXTVIEW_INSERT(_(" (Shortcut key: 't')\n"));
+
+#ifndef MAEMO
+       TEXTVIEW_INSERT(_(" (Shortcut key: 't')"));
+#endif
+       TEXTVIEW_INSERT("\n");
+
        TEXTVIEW_INSERT(_("     - To open with an external program, select "));
        TEXTVIEW_INSERT_LINK(_("'Open'"), "sc://open", NULL);
+
+#ifndef MAEMO
        TEXTVIEW_INSERT(_(" (Shortcut key: 'l')\n"));
        TEXTVIEW_INSERT(_("       (alternately double-click, or click the middle "));
        TEXTVIEW_INSERT(_("mouse button)\n"));
        TEXTVIEW_INSERT(_("     - Or use "));
        TEXTVIEW_INSERT_LINK(_("'Open with...'"), "sc://open_with", NULL);
-       TEXTVIEW_INSERT(_(" (Shortcut key: 'o')\n"));
+       TEXTVIEW_INSERT(_(" (Shortcut key: 'o')"));
+#endif
+       TEXTVIEW_INSERT("\n");
+
        textview_show_icon(textview, GTK_STOCK_DIALOG_INFO);
 }
 
@@ -882,7 +919,6 @@ static void textview_write_body(TextView *textview, MimeInfo *mimeinfo)
        CodeConverter *conv;
        const gchar *charset, *p, *cmd;
        GSList *cur;
-       int lines = 0;
        
        if (textview->messageview->forced_charset)
                charset = textview->messageview->forced_charset;
@@ -960,7 +996,7 @@ static void textview_write_body(TextView *textview, MimeInfo *mimeinfo)
                        dup(pfd[1]);
                        rc = execvp(argv[0], argv);
                        close(pfd[1]);
-                       printf (_("The command to view attachment "
+                       g_print(_("The command to view attachment "
                                "as text failed:\n"
                                "    %s\n"
                                "Exit code %d\n"), buf, rc);
@@ -971,9 +1007,6 @@ static void textview_write_body(TextView *textview, MimeInfo *mimeinfo)
                while (fgets(buf, sizeof(buf), tmpfp)) {
                        textview_write_line(textview, buf, conv, TRUE);
                        
-                       lines++;
-                       if (lines % 500 == 0)
-                               GTK_EVENTS_FLUSH();
                        if (textview->stop_loading) {
                                fclose(tmpfp);
                                waitpid(pid, pfd, 0);
@@ -988,16 +1021,12 @@ static void textview_write_body(TextView *textview, MimeInfo *mimeinfo)
 #endif
        } else {
 textview_default:
-               lines = 0;
                tmpfp = g_fopen(mimeinfo->data.filename, "rb");
                fseek(tmpfp, mimeinfo->offset, SEEK_SET);
                debug_print("Viewing text content of type: %s (length: %d)\n", mimeinfo->subtype, mimeinfo->length);
                while ((ftell(tmpfp) < mimeinfo->offset + mimeinfo->length) &&
                       (fgets(buf, sizeof(buf), tmpfp) != NULL)) {
                        textview_write_line(textview, buf, conv, TRUE);
-                       lines++;
-                       if (lines % 500 == 0)
-                               GTK_EVENTS_FLUSH();
                        if (textview->stop_loading) {
                                fclose(tmpfp);
                                return;
@@ -1009,7 +1038,6 @@ textview_default:
        conv_code_converter_destroy(conv);
        procmime_force_encoding(0);
 
-       lines = 0;
        textview->uri_list = g_slist_reverse(textview->uri_list);
        for (cur = textview->uri_list; cur; cur = cur->next) {
                ClickableText *uri = (ClickableText *)cur->data;
@@ -1018,14 +1046,13 @@ textview_default:
                if (!prefs_common.hide_quotes ||
                    uri->quote_level+1 < prefs_common.hide_quotes) {
                        textview_toggle_quote(textview, cur, uri, TRUE);
-                       lines++;
-                       if (lines % 500 == 0)
-                               GTK_EVENTS_FLUSH();
                        if (textview->stop_loading) {
                                return;
                        }
                }
        }
+       
+       GTK_EVENTS_FLUSH();
 }
 
 static void textview_show_html(TextView *textview, FILE *fp,
@@ -1458,7 +1485,7 @@ do_quote:
                        if (textview->uri_list) {
                                lasturi = (ClickableText *)last->data;
                        } else {
-                               printf("oops (%d %d)\n",
+                               g_print("oops (%d %d)\n",
                                        real_quotelevel, textview->prev_quote_level);
                        }               
                        if (lasturi->is_quote == FALSE) {
@@ -1878,6 +1905,101 @@ bail:
 }
 #endif
 
+static void textview_save_contact_pic(TextView *textview)
+{
+       MsgInfo *msginfo = textview->messageview->msginfo;
+       gchar *filename = NULL;
+       GError *error = NULL;
+       GdkPixbuf *picture = NULL;
+                               
+       if (!msginfo->extradata || (!msginfo->extradata->face && !msginfo->extradata->xface))
+               return;
+
+       if (textview->image) 
+               picture = gtk_image_get_pixbuf(GTK_IMAGE(textview->image));
+
+       filename = addrindex_get_picture_file(msginfo->from);
+       if (!filename)
+               return;
+       if (!is_file_exist(filename)) {
+               gdk_pixbuf_save(picture, filename, "png", &error, NULL);
+               if (error) {
+                       g_warning(_("Failed to save image: \n%s"),
+                                       error->message);
+                       g_error_free(error);
+               }
+       }
+       g_free(filename);
+}
+
+static void textview_show_contact_pic(TextView *textview)
+{
+       MsgInfo *msginfo = textview->messageview->msginfo;
+       GtkTextView *text = GTK_TEXT_VIEW(textview->text);
+       int x = 0;
+       gchar *filename = NULL;
+       GError *error = NULL;
+       GdkPixbuf *picture = NULL;
+       gint w, h;
+                               
+       if (prefs_common.display_header_pane
+       ||  !prefs_common.display_xface)
+               goto bail;
+       
+       if (msginfo->extradata && (msginfo->extradata->face || msginfo->extradata->xface))
+               return;
+
+       if (textview->image) 
+               gtk_widget_destroy(textview->image);
+
+       filename = addrindex_get_picture_file(msginfo->from);
+       
+       if (!filename)
+               goto bail;
+       if (!is_file_exist(filename)) {
+               g_free(filename);
+               goto bail;
+       }
+
+       gdk_pixbuf_get_file_info(filename, &w, &h);
+       
+       if (w > 48 || h > 48)
+               picture = gdk_pixbuf_new_from_file_at_scale(filename, 
+                                               48, 48, TRUE, &error);
+       else
+               picture = gdk_pixbuf_new_from_file(filename, &error);
+
+       if (error) {
+               debug_print("Failed to import image: \n%s",
+                               error->message);
+               g_error_free(error);
+               goto bail;
+       }
+       g_free(filename);
+
+       if (picture) {
+               textview->image = gtk_image_new_from_pixbuf(picture);
+               g_object_unref(picture);
+       }
+       g_return_if_fail(textview->image != NULL);
+
+       gtk_widget_show(textview->image);
+       
+       x = textview->text->allocation.width - WIDTH -5;
+
+       gtk_text_view_add_child_in_window(text, textview->image, 
+               GTK_TEXT_WINDOW_TEXT, x, 5);
+
+       gtk_widget_show_all(textview->text);
+       
+       return;
+bail:
+       if (textview->image) 
+               gtk_widget_destroy(textview->image);
+       textview->image = NULL;
+       
+}
+
 static void textview_show_tags(TextView *textview)
 {
        MsgInfo *msginfo = textview->messageview->msginfo;
@@ -2001,6 +2123,8 @@ static void textview_show_header(TextView *textview, GPtrArray *headers)
 #if HAVE_LIBCOMPFACE
        textview_show_xface(textview);
 #endif
+       textview_save_contact_pic(textview);
+       textview_show_contact_pic(textview);
 }
 
 gboolean textview_search_string(TextView *textview, const gchar *str,
@@ -2087,6 +2211,7 @@ static gint textview_key_pressed(GtkWidget *widget, GdkEventKey *event,
        case GDK_y:
        case GDK_t:
        case GDK_l:
+       case GDK_o:
        case GDK_c:
        case GDK_a:
                if ((event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK)) == 0) {
@@ -2785,17 +2910,42 @@ static void add_uri_to_addrbook_cb (TextView *textview, guint action, void *data
        gchar *fromname, *fromaddress;
        ClickableText *uri = g_object_get_data(G_OBJECT(textview->mail_popup_menu),
                                           "menu_button");
+       GtkWidget *image = NULL;
+       GdkPixbuf *picture = NULL;
+       gboolean use_picture = FALSE;
        if (uri == NULL)
                return;
 
        /* extract url */
        fromaddress = g_strdup(uri->uri + 7);
-       /* Hiroyuki: please put this function in utils.c! */
+       
+       if (textview->messageview->msginfo &&
+          !strcmp2(fromaddress, textview->messageview->msginfo->from))
+               use_picture = TRUE;
+
        fromname = procheader_get_fromname(fromaddress);
        extract_address(fromaddress);
 
-       /* Add to address book - Match */
-       addressbook_add_contact( fromname, fromaddress, NULL );
+       if (use_picture && 
+           textview->messageview->msginfo &&
+           textview->messageview->msginfo->extradata &&
+           textview->messageview->msginfo->extradata->face) {
+               image = face_get_from_header(textview->messageview->msginfo->extradata->face);
+       }
+#if HAVE_LIBCOMPFACE 
+       else if (use_picture && 
+                textview->messageview->msginfo &&
+                textview->messageview->msginfo->extradata &&
+                textview->messageview->msginfo->extradata->xface) {
+               image = xface_get_from_header(textview->messageview->msginfo->extradata->xface,
+                               &textview->text->style->white,
+                               mainwindow_get_mainwindow()->window->window);   
+       }
+#endif
+       if (image)
+               picture = gtk_image_get_pixbuf(GTK_IMAGE(image));
+
+       addressbook_add_contact( fromname, fromaddress, NULL, picture);
 
        g_free(fromaddress);
        g_free(fromname);