added support to text/enriched
[claws.git] / src / mimeview.c
index b72fd644553fd63b6d27d600356ee9d03fdfc5ff..14e043880b6b79ee8bdf629943d1b28b69aeee29 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999,2000 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2001 Hiroyuki Yamamoto
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include "menu.h"
 #include "filesel.h"
 #include "alertpanel.h"
+#include "inputdialog.h"
 #include "utils.h"
 #include "gtkutils.h"
 #include "prefs_common.h"
 #include "rfc2015.h"
+#include "pgptext.h"
 
 typedef enum
 {
@@ -71,7 +73,7 @@ static void mimeview_show_message_part                (MimeView       *mimeview,
 static void mimeview_show_image_part           (MimeView       *mimeview,
                                                 MimeInfo       *partinfo);
 static void mimeview_change_view_type          (MimeView       *mimeview,
-                                                ContentType     type);
+                                                MimeViewType    type);
 static void mimeview_clear                     (MimeView       *mimeview);
 
 static void mimeview_selected          (GtkCTree       *ctree,
@@ -99,8 +101,10 @@ static void mimeview_drag_data_get      (GtkWidget    *widget,
 static void mimeview_display_as_text   (MimeView       *mimeview);
 static void mimeview_save_as           (MimeView       *mimeview);
 static void mimeview_launch            (MimeView       *mimeview);
+static void mimeview_open_with         (MimeView       *mimeview);
 static void mimeview_view_file         (const gchar    *filename,
-                                        MimeInfo       *partinfo);
+                                        MimeInfo       *partinfo,
+                                        const gchar    *cmdline);
 #if USE_GPGME
 static void mimeview_check_signature   (MimeView       *mimeview);
 #endif
@@ -108,6 +112,7 @@ static void mimeview_check_signature        (MimeView       *mimeview);
 static GtkItemFactoryEntry mimeview_popup_entries[] =
 {
        {N_("/_Open"),            NULL, mimeview_launch,          0, NULL},
+       {N_("/Open _with..."),    NULL, mimeview_open_with,       0, NULL},
        {N_("/_Display as text"), NULL, mimeview_display_as_text, 0, NULL},
        {N_("/_Save as..."),      NULL, mimeview_save_as,         0, NULL}
 #if USE_GPGME
@@ -146,7 +151,7 @@ MimeView *mimeview_create(void)
        gtk_widget_set_usize(scrolledwin, -1, 80);
 
        ctree = gtk_sctree_new_with_titles(N_MIMEVIEW_COLS, 0, titles);
-       gtk_clist_set_selection_mode(GTK_CLIST(ctree), GTK_SELECTION_BROWSE);//SINGLE);
+       gtk_clist_set_selection_mode(GTK_CLIST(ctree), GTK_SELECTION_BROWSE);
        gtk_ctree_set_line_style(GTK_CTREE(ctree), GTK_CTREE_LINES_NONE);
        gtk_clist_set_column_justification(GTK_CLIST(ctree), COL_SIZE,
                                           GTK_JUSTIFY_RIGHT);
@@ -221,6 +226,8 @@ static gboolean mimeview_is_signed(MimeView *mimeview)
        do {
                if (rfc2015_has_signature(partinfo))
                        return TRUE;
+               if (pgptext_has_signature(partinfo))
+                       return TRUE;
         } while ((partinfo = partinfo->parent) != NULL);
 
        debug_print("mimeview_is_signed: FALSE\n" );
@@ -242,7 +249,7 @@ static void set_unchecked_signature(MimeInfo *mimeinfo)
        g_free(sig_partinfo->sigstatus_full);
        sig_partinfo->sigstatus_full = NULL;
 }
-#endif /*USE_GPGME*/
+#endif /* USE_GPGME */
 
 void mimeview_show_message(MimeView *mimeview, MimeInfo *mimeinfo,
                           const gchar *file)
@@ -265,7 +272,7 @@ void mimeview_show_message(MimeView *mimeview, MimeInfo *mimeinfo,
        }
        mimeview->file = g_strdup(file);
 
-       /* skip headers */
+       /* skip MIME part headers */
        if (mimeinfo->mime_type == MIME_MULTIPART) {
                if (fseek(fp, mimeinfo->fpos, SEEK_SET) < 0)
                perror("fseek");
@@ -290,8 +297,21 @@ void mimeview_show_message(MimeView *mimeview, MimeInfo *mimeinfo,
        gtk_signal_handler_unblock_by_func(GTK_OBJECT(ctree),
                                           mimeview_selected, mimeview);
 
-       if ((node = gtk_ctree_node_nth(ctree, 0))) {
+       /* search first text part */
+       for (node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
+            node != NULL; node = GTK_CTREE_NODE_NEXT(node)) {
+               MimeInfo *partinfo;
+
+               partinfo = gtk_ctree_node_get_row_data(ctree, node);
+               if (partinfo && partinfo->mime_type == MIME_TEXT)
+                       break;
+       }
+       if (!node)
+               node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
+
+       if (node) {
                gtk_ctree_select(ctree, node);
+               gtkut_ctree_set_focus_row(ctree, node);
                gtk_widget_grab_focus(mimeview->ctree);
        }
 }
@@ -473,9 +493,17 @@ static void mimeview_selected(GtkCTree *ctree, GtkCTreeNode *node, gint column,
        partinfo = gtk_ctree_node_get_row_data(ctree, node);
        if (!partinfo) return;
 
+       /* ungrab the mouse event */
+       if (GTK_WIDGET_HAS_GRAB(ctree)) {
+               gtk_grab_remove(GTK_WIDGET(ctree));
+               if (gdk_pointer_is_grabbed())
+                       gdk_pointer_ungrab(GDK_CURRENT_TIME);
+       }
+
        switch (partinfo->mime_type) {
        case MIME_TEXT:
        case MIME_TEXT_HTML:
+       case MIME_TEXT_ENRICHED:
        case MIME_MESSAGE_RFC822:
        case MIME_MULTIPART:
                mimeview_show_message_part(mimeview, partinfo);
@@ -545,6 +573,7 @@ static void mimeview_button_pressed(GtkWidget *widget, GdkEventButton *event,
                        (GTK_CTREE(mimeview->ctree), mimeview->opened);
                if (partinfo && (partinfo->mime_type == MIME_TEXT ||
                                 partinfo->mime_type == MIME_TEXT_HTML ||
+                                partinfo->mime_type == MIME_TEXT_ENRICHED ||
                                 partinfo->mime_type == MIME_MESSAGE_RFC822 ||
                                 partinfo->mime_type == MIME_IMAGE ||
                                 partinfo->mime_type == MIME_MULTIPART))
@@ -553,6 +582,13 @@ static void mimeview_button_pressed(GtkWidget *widget, GdkEventButton *event,
                else
                        menu_set_sensitive(mimeview->popupfactory,
                                           "/Display as text", TRUE);
+               if (partinfo &&
+                   partinfo->mime_type == MIME_APPLICATION_OCTET_STREAM)
+                       menu_set_sensitive(mimeview->popupfactory,
+                                          "/Open", FALSE);
+               else
+                       menu_set_sensitive(mimeview->popupfactory,
+                                          "/Open", TRUE);
 #if USE_GPGME
                menu_set_sensitive(mimeview->popupfactory,
                                   "/Check signature",
@@ -590,7 +626,6 @@ static void mimeview_key_pressed(GtkWidget *widget, GdkEventKey *event,
                }
                break;
        case GDK_BackSpace:
-       case GDK_Delete:
                textview_scroll_page(mimeview->textview, TRUE);
                return;
        case GDK_Return:
@@ -626,6 +661,7 @@ static void mimeview_key_pressed(GtkWidget *widget, GdkEventKey *event,
                mimeview_launch(mimeview);
                return;
        default:
+               break;
        }
 
        if (!mimeview->messageview->mainwin) return;
@@ -729,25 +765,72 @@ static void mimeview_launch(MimeView *mimeview)
                alertpanel_error
                        (_("Can't save the part of multipart message."));
        else
-               mimeview_view_file(filename, partinfo);
+               mimeview_view_file(filename, partinfo, NULL);
 
        g_free(filename);
 }
 
-static void mimeview_view_file(const gchar *filename, MimeInfo *partinfo)
+static void mimeview_open_with(MimeView *mimeview)
+{
+       MimeInfo *partinfo;
+       gchar *filename;
+       gchar *cmd;
+
+       if (!mimeview->opened) return;
+       if (!mimeview->file) return;
+
+       partinfo = gtk_ctree_node_get_row_data
+               (GTK_CTREE(mimeview->ctree), mimeview->opened);
+       g_return_if_fail(partinfo != NULL);
+
+       filename = procmime_get_tmp_file_name(partinfo);
+
+       if (procmime_get_part(filename, mimeview->file, partinfo) < 0) {
+               alertpanel_error
+                       (_("Can't save the part of multipart message."));
+               g_free(filename);
+               return;
+       }
+
+       if (!prefs_common.mime_open_cmd_history)
+               prefs_common.mime_open_cmd_history =
+                       add_history(NULL, prefs_common.mime_open_cmd);
+
+       cmd = input_dialog_combo
+               (_("Open with"),
+                _("Enter the command line to open file:\n"
+                  "(`%s' will be replaced with file name)"),
+                prefs_common.mime_open_cmd,
+                prefs_common.mime_open_cmd_history);
+       if (cmd) {
+               mimeview_view_file(filename, partinfo, cmd);
+               g_free(prefs_common.mime_open_cmd);
+               prefs_common.mime_open_cmd = cmd;
+               prefs_common.mime_open_cmd_history =
+                       add_history(prefs_common.mime_open_cmd_history, cmd);
+       }
+
+       g_free(filename);
+}
+
+static void mimeview_view_file(const gchar *filename, MimeInfo *partinfo,
+                              const gchar *cmdline)
 {
        static gchar *default_image_cmdline = "display '%s'";
        static gchar *default_audio_cmdline = "play '%s'";
        static gchar *default_html_cmdline =
                "netscape -remote 'openURL(%s,raise)'";
-       static gchar *mime_cmdline = "metamail -d -b -c %s '%s'";
+       static gchar *mime_cmdline = "metamail -d -b -x -c %s '%s'";
        gchar buf[1024];
        gchar m_buf[1024];
-       gchar *cmd;
-       gchar *def_cmd;
-       gchar *p;
+       const gchar *cmd;
+       const gchar *def_cmd;
+       const gchar *p;
 
-       if (MIME_APPLICATION_OCTET_STREAM == partinfo->mime_type) {
+       if (cmdline) {
+               cmd = cmdline;
+               def_cmd = NULL;
+       } else if (MIME_APPLICATION_OCTET_STREAM == partinfo->mime_type) {
                return;
        } else if (MIME_IMAGE == partinfo->mime_type) {
                cmd = prefs_common.mime_image_viewer;
@@ -777,7 +860,7 @@ static void mimeview_view_file(const gchar *filename, MimeInfo *partinfo)
                        return;
        }
 
-       execute_command_line(buf);
+       execute_command_line(buf, TRUE);
 }
 
 #if USE_GPGME
@@ -855,4 +938,4 @@ static void mimeview_check_signature(MimeView *mimeview)
        mimeview_update_names(mimeview);
        mimeview_update_signature_info(mimeview);
 }
-#endif /*USE_GPGME*/
+#endif /* USE_GPGME */