Statistics
| Revision:

root / src / mimeview.c @ 56

History | View | Annotate | Download (25.8 kB)

1 1 hiro
/*
2 1 hiro
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 1 hiro
 * Copyright (C) 1999-2004 Hiroyuki Yamamoto
4 1 hiro
 *
5 1 hiro
 * This program is free software; you can redistribute it and/or modify
6 1 hiro
 * it under the terms of the GNU General Public License as published by
7 1 hiro
 * the Free Software Foundation; either version 2 of the License, or
8 1 hiro
 * (at your option) any later version.
9 1 hiro
 *
10 1 hiro
 * This program is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 1 hiro
 * GNU General Public License for more details.
14 1 hiro
 *
15 1 hiro
 * You should have received a copy of the GNU General Public License
16 1 hiro
 * along with this program; if not, write to the Free Software
17 1 hiro
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 1 hiro
 */
19 1 hiro
20 1 hiro
#ifdef HAVE_CONFIG_H
21 1 hiro
#  include "config.h"
22 1 hiro
#endif
23 1 hiro
24 1 hiro
#include "defs.h"
25 1 hiro
26 1 hiro
#include <glib.h>
27 1 hiro
#include <gdk/gdkkeysyms.h>
28 1 hiro
#include <gtk/gtknotebook.h>
29 1 hiro
#include <gtk/gtkscrolledwindow.h>
30 1 hiro
#include <gtk/gtkctree.h>
31 1 hiro
#include <gtk/gtkvbox.h>
32 1 hiro
#include <gtk/gtkvpaned.h>
33 1 hiro
#include <gtk/gtksignal.h>
34 1 hiro
#include <gtk/gtkmenu.h>
35 1 hiro
#include <gtk/gtkdnd.h>
36 1 hiro
#include <gtk/gtkselection.h>
37 1 hiro
#include <stdio.h>
38 1 hiro
#include <unistd.h>
39 1 hiro
40 1 hiro
#include "intl.h"
41 1 hiro
#include "main.h"
42 1 hiro
#include "mimeview.h"
43 1 hiro
#include "textview.h"
44 1 hiro
#include "imageview.h"
45 1 hiro
#include "procmime.h"
46 1 hiro
#include "summaryview.h"
47 1 hiro
#include "menu.h"
48 1 hiro
#include "filesel.h"
49 1 hiro
#include "alertpanel.h"
50 1 hiro
#include "inputdialog.h"
51 1 hiro
#include "utils.h"
52 1 hiro
#include "gtkutils.h"
53 1 hiro
#include "prefs_common.h"
54 1 hiro
#include "rfc2015.h"
55 1 hiro
56 1 hiro
typedef enum
57 1 hiro
{
58 1 hiro
        COL_MIMETYPE = 0,
59 1 hiro
        COL_SIZE     = 1,
60 1 hiro
        COL_NAME     = 2
61 1 hiro
} MimeViewColumnPos;
62 1 hiro
63 1 hiro
#define N_MIMEVIEW_COLS        3
64 1 hiro
65 1 hiro
static void mimeview_set_multipart_tree                (MimeView        *mimeview,
66 1 hiro
                                                 MimeInfo        *mimeinfo,
67 1 hiro
                                                 GtkCTreeNode        *parent);
68 1 hiro
static GtkCTreeNode *mimeview_append_part        (MimeView        *mimeview,
69 1 hiro
                                                 MimeInfo        *partinfo,
70 1 hiro
                                                 GtkCTreeNode        *parent);
71 1 hiro
static void mimeview_show_message_part                (MimeView        *mimeview,
72 1 hiro
                                                 MimeInfo        *partinfo);
73 1 hiro
static void mimeview_show_image_part                (MimeView        *mimeview,
74 1 hiro
                                                 MimeInfo        *partinfo);
75 1 hiro
static void mimeview_change_view_type                (MimeView        *mimeview,
76 1 hiro
                                                 MimeViewType         type);
77 1 hiro
78 1 hiro
static void mimeview_selected                (GtkCTree        *ctree,
79 1 hiro
                                         GtkCTreeNode        *node,
80 1 hiro
                                         gint                 column,
81 1 hiro
                                         MimeView        *mimeview);
82 1 hiro
static void mimeview_start_drag         (GtkWidget        *widget,
83 1 hiro
                                         gint                 button,
84 1 hiro
                                         GdkEvent        *event,
85 1 hiro
                                         MimeView        *mimeview);
86 1 hiro
static gint mimeview_button_pressed        (GtkWidget        *widget,
87 1 hiro
                                         GdkEventButton        *event,
88 1 hiro
                                         MimeView        *mimeview);
89 1 hiro
static gint mimeview_key_pressed        (GtkWidget        *widget,
90 1 hiro
                                         GdkEventKey        *event,
91 1 hiro
                                         MimeView        *mimeview);
92 1 hiro
93 1 hiro
static void mimeview_drag_data_get      (GtkWidget          *widget,
94 1 hiro
                                         GdkDragContext   *drag_context,
95 1 hiro
                                         GtkSelectionData *selection_data,
96 1 hiro
                                         guint                   info,
97 1 hiro
                                         guint                   time,
98 1 hiro
                                         MimeView          *mimeview);
99 1 hiro
100 1 hiro
static void mimeview_display_as_text        (MimeView        *mimeview);
101 1 hiro
static void mimeview_save_as                (MimeView        *mimeview);
102 1 hiro
static void mimeview_launch                (MimeView        *mimeview);
103 1 hiro
static void mimeview_open_with                (MimeView        *mimeview);
104 1 hiro
static void mimeview_view_file                (const gchar        *filename,
105 1 hiro
                                         MimeInfo        *partinfo,
106 1 hiro
                                         const gchar        *cmdline);
107 1 hiro
#if USE_GPGME
108 1 hiro
static void mimeview_check_signature        (MimeView        *mimeview);
109 1 hiro
#endif
110 1 hiro
111 1 hiro
static GtkItemFactoryEntry mimeview_popup_entries[] =
112 1 hiro
{
113 1 hiro
        {N_("/_Open"),                  NULL, mimeview_launch,          0, NULL},
114 1 hiro
        {N_("/Open _with..."),          NULL, mimeview_open_with,          0, NULL},
115 1 hiro
        {N_("/_Display as text"), NULL, mimeview_display_as_text, 0, NULL},
116 1 hiro
        {N_("/_Save as..."),          NULL, mimeview_save_as,          0, NULL}
117 1 hiro
#if USE_GPGME
118 1 hiro
        ,
119 1 hiro
        {N_("/_Check signature"), NULL, mimeview_check_signature, 0, NULL}
120 1 hiro
#endif
121 1 hiro
};
122 1 hiro
123 1 hiro
static GtkTargetEntry mimeview_mime_types[] =
124 1 hiro
{
125 1 hiro
        {"text/uri-list", 0, 0}
126 1 hiro
};
127 1 hiro
128 1 hiro
MimeView *mimeview_create(void)
129 1 hiro
{
130 1 hiro
        MimeView *mimeview;
131 1 hiro
132 1 hiro
        GtkWidget *notebook;
133 1 hiro
        GtkWidget *vbox;
134 1 hiro
        GtkWidget *paned;
135 1 hiro
        GtkWidget *scrolledwin;
136 1 hiro
        GtkWidget *ctree;
137 1 hiro
        GtkWidget *mime_vbox;
138 1 hiro
        GtkWidget *popupmenu;
139 1 hiro
        GtkItemFactory *popupfactory;
140 1 hiro
        gchar *titles[N_MIMEVIEW_COLS];
141 1 hiro
        gint n_entries;
142 1 hiro
        gint i;
143 1 hiro
144 1 hiro
        debug_print(_("Creating MIME view...\n"));
145 1 hiro
        mimeview = g_new0(MimeView, 1);
146 1 hiro
147 1 hiro
        titles[COL_MIMETYPE] = _("MIME Type");
148 1 hiro
        titles[COL_SIZE]     = _("Size");
149 1 hiro
        titles[COL_NAME]     = _("Name");
150 1 hiro
151 1 hiro
        notebook = gtk_notebook_new();
152 1 hiro
        gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), TRUE);
153 1 hiro
154 1 hiro
        vbox = gtk_vbox_new(FALSE, 0);
155 1 hiro
        gtk_container_add(GTK_CONTAINER(notebook), vbox);
156 1 hiro
        gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(notebook), vbox,
157 1 hiro
                                        _("Text"));
158 1 hiro
159 1 hiro
        scrolledwin = gtk_scrolled_window_new(NULL, NULL);
160 1 hiro
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
161 1 hiro
                                       GTK_POLICY_AUTOMATIC,
162 1 hiro
                                       GTK_POLICY_ALWAYS);
163 1 hiro
        gtk_widget_set_size_request(scrolledwin, -1, 80);
164 1 hiro
165 1 hiro
        ctree = gtk_sctree_new_with_titles(N_MIMEVIEW_COLS, 0, titles);
166 1 hiro
        gtk_clist_set_selection_mode(GTK_CLIST(ctree), GTK_SELECTION_BROWSE);
167 1 hiro
        gtk_ctree_set_line_style(GTK_CTREE(ctree), GTK_CTREE_LINES_NONE);
168 1 hiro
        gtk_clist_set_column_justification(GTK_CLIST(ctree), COL_SIZE,
169 1 hiro
                                           GTK_JUSTIFY_RIGHT);
170 1 hiro
        gtk_clist_set_column_width(GTK_CLIST(ctree), COL_MIMETYPE, 240);
171 1 hiro
        gtk_clist_set_column_width(GTK_CLIST(ctree), COL_SIZE, 64);
172 1 hiro
        for (i = 0; i < N_MIMEVIEW_COLS; i++)
173 1 hiro
                GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(ctree)->column[i].button,
174 1 hiro
                                       GTK_CAN_FOCUS);
175 1 hiro
        gtk_container_add(GTK_CONTAINER(scrolledwin), ctree);
176 1 hiro
177 1 hiro
        g_signal_connect(G_OBJECT(ctree), "tree_select_row",
178 1 hiro
                         G_CALLBACK(mimeview_selected), mimeview);
179 1 hiro
        g_signal_connect(G_OBJECT(ctree), "button_press_event",
180 1 hiro
                         G_CALLBACK(mimeview_button_pressed), mimeview);
181 1 hiro
        g_signal_connect(G_OBJECT(ctree), "key_press_event",
182 1 hiro
                         G_CALLBACK(mimeview_key_pressed), mimeview);
183 1 hiro
        g_signal_connect(G_OBJECT (ctree),"start_drag",
184 1 hiro
                         G_CALLBACK (mimeview_start_drag), mimeview);
185 1 hiro
        g_signal_connect(G_OBJECT(ctree), "drag_data_get",
186 1 hiro
                         G_CALLBACK(mimeview_drag_data_get), mimeview);
187 1 hiro
188 1 hiro
        mime_vbox = gtk_vbox_new(FALSE, 0);
189 1 hiro
190 1 hiro
        paned = gtk_vpaned_new();
191 1 hiro
        gtk_paned_add1(GTK_PANED(paned), scrolledwin);
192 1 hiro
        gtk_paned_add2(GTK_PANED(paned), mime_vbox);
193 1 hiro
        gtk_container_add(GTK_CONTAINER(notebook), paned);
194 1 hiro
        gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(notebook), paned,
195 1 hiro
                                        _("Attachments"));
196 1 hiro
197 1 hiro
        gtk_widget_show_all(notebook);
198 1 hiro
199 1 hiro
        gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0);
200 1 hiro
201 1 hiro
        n_entries = sizeof(mimeview_popup_entries) /
202 1 hiro
                sizeof(mimeview_popup_entries[0]);
203 1 hiro
        popupmenu = menu_create_items(mimeview_popup_entries, n_entries,
204 1 hiro
                                      "<MimeView>", &popupfactory, mimeview);
205 1 hiro
206 1 hiro
        mimeview->notebook     = notebook;
207 1 hiro
        mimeview->vbox         = vbox;
208 1 hiro
        mimeview->paned        = paned;
209 1 hiro
        mimeview->scrolledwin  = scrolledwin;
210 1 hiro
        mimeview->ctree        = ctree;
211 1 hiro
        mimeview->mime_vbox    = mime_vbox;
212 1 hiro
        mimeview->popupmenu    = popupmenu;
213 1 hiro
        mimeview->popupfactory = popupfactory;
214 1 hiro
        mimeview->type         = -1;
215 1 hiro
216 1 hiro
        return mimeview;
217 1 hiro
}
218 1 hiro
219 1 hiro
void mimeview_init(MimeView *mimeview)
220 1 hiro
{
221 1 hiro
        textview_init(mimeview->textview);
222 1 hiro
        imageview_init(mimeview->imageview);
223 1 hiro
}
224 1 hiro
225 1 hiro
/*
226 1 hiro
 * Check whether the message is OpenPGP signed
227 1 hiro
 */
228 1 hiro
#if USE_GPGME
229 1 hiro
static gboolean mimeview_is_signed(MimeView *mimeview)
230 1 hiro
{
231 1 hiro
        MimeInfo *partinfo;
232 1 hiro
233 1 hiro
        debug_print("mimeview_is signed of %p\n", mimeview);
234 1 hiro
235 1 hiro
        if (!mimeview) return FALSE;
236 1 hiro
        if (!mimeview->opened) return FALSE;
237 1 hiro
238 1 hiro
        debug_print("mimeview_is_signed: open\n" );
239 1 hiro
240 1 hiro
        if (!mimeview->file) return FALSE;
241 1 hiro
242 1 hiro
        debug_print("mimeview_is_signed: file\n" );
243 1 hiro
244 1 hiro
        partinfo = mimeview_get_selected_part(mimeview);
245 1 hiro
        g_return_val_if_fail(partinfo != NULL, FALSE);
246 1 hiro
247 1 hiro
        /* walk the tree and see whether there is a signature somewhere */
248 1 hiro
        do {
249 1 hiro
                if (rfc2015_has_signature(partinfo))
250 1 hiro
                        return TRUE;
251 1 hiro
        } while ((partinfo = partinfo->parent) != NULL);
252 1 hiro
253 1 hiro
        debug_print("mimeview_is_signed: FALSE\n" );
254 1 hiro
255 1 hiro
        return FALSE;
256 1 hiro
}
257 1 hiro
258 1 hiro
static void set_unchecked_signature(MimeInfo *mimeinfo)
259 1 hiro
{
260 56 hiro
        MimeInfo **signedinfo;
261 1 hiro
262 56 hiro
        signedinfo = rfc2015_find_signature(mimeinfo);
263 56 hiro
        if (signedinfo == NULL) return;
264 1 hiro
265 56 hiro
        g_free(signedinfo[1]->sigstatus);
266 56 hiro
        signedinfo[1]->sigstatus =
267 1 hiro
                g_strdup(_("Select \"Check signature\" to check"));
268 1 hiro
269 56 hiro
        g_free(signedinfo[1]->sigstatus_full);
270 56 hiro
        signedinfo[1]->sigstatus_full = NULL;
271 56 hiro
272 56 hiro
    g_free(signedinfo);
273 1 hiro
}
274 1 hiro
#endif /* USE_GPGME */
275 1 hiro
276 1 hiro
void mimeview_show_message(MimeView *mimeview, MimeInfo *mimeinfo,
277 1 hiro
                           const gchar *file)
278 1 hiro
{
279 1 hiro
        GtkCTree *ctree = GTK_CTREE(mimeview->ctree);
280 1 hiro
        GtkCTreeNode *node;
281 1 hiro
282 1 hiro
        mimeview_clear(mimeview);
283 1 hiro
        textview_clear(mimeview->messageview->textview);
284 1 hiro
285 1 hiro
        g_return_if_fail(file != NULL);
286 1 hiro
        g_return_if_fail(mimeinfo != NULL);
287 1 hiro
288 1 hiro
        mimeview->mimeinfo = mimeinfo;
289 1 hiro
290 1 hiro
        mimeview->file = g_strdup(file);
291 1 hiro
292 1 hiro
#if USE_GPGME
293 1 hiro
        if (prefs_common.auto_check_signatures) {
294 1 hiro
                FILE *fp;
295 1 hiro
296 1 hiro
                if ((fp = fopen(file, "rb")) == NULL) {
297 1 hiro
                        FILE_OP_ERROR(file, "fopen");
298 1 hiro
                        return;
299 1 hiro
                }
300 1 hiro
                rfc2015_check_signature(mimeinfo, fp);
301 1 hiro
                fclose(fp);
302 1 hiro
        } else
303 1 hiro
                set_unchecked_signature(mimeinfo);
304 1 hiro
#endif
305 1 hiro
306 1 hiro
        g_signal_handlers_block_by_func
307 1 hiro
                (G_OBJECT(ctree), G_CALLBACK(mimeview_selected), mimeview);
308 1 hiro
309 1 hiro
        mimeview_set_multipart_tree(mimeview, mimeinfo, NULL);
310 1 hiro
311 1 hiro
        g_signal_handlers_unblock_by_func
312 1 hiro
                (G_OBJECT(ctree), G_CALLBACK(mimeview_selected), mimeview);
313 1 hiro
314 1 hiro
        /* search first text part */
315 1 hiro
        for (node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
316 1 hiro
             node != NULL; node = GTK_CTREE_NODE_NEXT(node)) {
317 1 hiro
                MimeInfo *partinfo;
318 1 hiro
319 1 hiro
                partinfo = gtk_ctree_node_get_row_data(ctree, node);
320 1 hiro
                if (partinfo &&
321 1 hiro
                    (partinfo->mime_type == MIME_TEXT ||
322 1 hiro
                     partinfo->mime_type == MIME_TEXT_HTML))
323 1 hiro
                        break;
324 1 hiro
        }
325 1 hiro
        textview_show_message(mimeview->messageview->textview, mimeinfo, file);
326 1 hiro
327 1 hiro
        if (!node)
328 1 hiro
                node = GTK_CTREE_NODE(GTK_CLIST(ctree)->row_list);
329 1 hiro
330 1 hiro
        if (node) {
331 1 hiro
                gtk_ctree_select(ctree, node);
332 1 hiro
                gtkut_ctree_set_focus_row(ctree, node);
333 1 hiro
                gtk_widget_grab_focus(mimeview->ctree);
334 1 hiro
        }
335 1 hiro
}
336 1 hiro
337 1 hiro
void mimeview_clear(MimeView *mimeview)
338 1 hiro
{
339 1 hiro
        GtkCList *clist = GTK_CLIST(mimeview->ctree);
340 1 hiro
341 1 hiro
        procmime_mimeinfo_free_all(mimeview->mimeinfo);
342 1 hiro
        mimeview->mimeinfo = NULL;
343 1 hiro
344 1 hiro
        gtk_clist_clear(clist);
345 1 hiro
        textview_clear(mimeview->textview);
346 1 hiro
        imageview_clear(mimeview->imageview);
347 1 hiro
348 1 hiro
        mimeview->opened = NULL;
349 1 hiro
350 1 hiro
        g_free(mimeview->file);
351 1 hiro
        mimeview->file = NULL;
352 1 hiro
353 1 hiro
        /* gtk_notebook_set_page(GTK_NOTEBOOK(mimeview->notebook), 0); */
354 1 hiro
}
355 1 hiro
356 1 hiro
void mimeview_destroy(MimeView *mimeview)
357 1 hiro
{
358 1 hiro
        textview_destroy(mimeview->textview);
359 1 hiro
        imageview_destroy(mimeview->imageview);
360 1 hiro
        procmime_mimeinfo_free_all(mimeview->mimeinfo);
361 1 hiro
        g_free(mimeview->file);
362 1 hiro
        g_free(mimeview);
363 1 hiro
}
364 1 hiro
365 1 hiro
MimeInfo *mimeview_get_selected_part(MimeView *mimeview)
366 1 hiro
{
367 1 hiro
        if (gtk_notebook_get_current_page
368 1 hiro
                (GTK_NOTEBOOK(mimeview->notebook)) == 0)
369 1 hiro
                return NULL;
370 1 hiro
371 1 hiro
        return gtk_ctree_node_get_row_data
372 1 hiro
                (GTK_CTREE(mimeview->ctree), mimeview->opened);
373 1 hiro
}
374 1 hiro
375 1 hiro
static void mimeview_set_multipart_tree(MimeView *mimeview,
376 1 hiro
                                        MimeInfo *mimeinfo,
377 1 hiro
                                        GtkCTreeNode *parent)
378 1 hiro
{
379 1 hiro
        GtkCTreeNode *node;
380 1 hiro
381 1 hiro
        g_return_if_fail(mimeinfo != NULL);
382 1 hiro
383 1 hiro
        if (mimeinfo->children)
384 1 hiro
                mimeinfo = mimeinfo->children;
385 1 hiro
386 1 hiro
        while (mimeinfo != NULL) {
387 1 hiro
                node = mimeview_append_part(mimeview, mimeinfo, parent);
388 1 hiro
389 1 hiro
                if (mimeinfo->children)
390 1 hiro
                        mimeview_set_multipart_tree(mimeview, mimeinfo, node);
391 1 hiro
                else if (mimeinfo->sub &&
392 1 hiro
                         mimeinfo->sub->mime_type != MIME_TEXT &&
393 1 hiro
                         mimeinfo->sub->mime_type != MIME_TEXT_HTML)
394 1 hiro
                        mimeview_set_multipart_tree(mimeview, mimeinfo->sub,
395 1 hiro
                                                    node);
396 1 hiro
                mimeinfo = mimeinfo->next;
397 1 hiro
        }
398 1 hiro
}
399 1 hiro
400 1 hiro
static gchar *get_part_name(MimeInfo *partinfo)
401 1 hiro
{
402 1 hiro
#if USE_GPGME
403 1 hiro
        if (partinfo->sigstatus)
404 1 hiro
                return partinfo->sigstatus;
405 1 hiro
        else
406 1 hiro
#endif
407 1 hiro
        if (partinfo->name)
408 1 hiro
                return partinfo->name;
409 1 hiro
        else if (partinfo->filename)
410 1 hiro
                return partinfo->filename;
411 1 hiro
        else
412 1 hiro
                return "";
413 1 hiro
}
414 1 hiro
415 1 hiro
static GtkCTreeNode *mimeview_append_part(MimeView *mimeview,
416 1 hiro
                                          MimeInfo *partinfo,
417 1 hiro
                                          GtkCTreeNode *parent)
418 1 hiro
{
419 1 hiro
        GtkCTree *ctree = GTK_CTREE(mimeview->ctree);
420 1 hiro
        GtkCTreeNode *node;
421 1 hiro
        gchar *str[N_MIMEVIEW_COLS];
422 1 hiro
423 1 hiro
        str[COL_MIMETYPE] =
424 1 hiro
                partinfo->content_type ? partinfo->content_type : "";
425 1 hiro
        str[COL_SIZE] = to_human_readable(partinfo->size);
426 1 hiro
        str[COL_NAME] = get_part_name(partinfo);
427 1 hiro
428 1 hiro
        node = gtk_ctree_insert_node(ctree, parent, NULL, str, 0,
429 1 hiro
                                     NULL, NULL, NULL, NULL,
430 1 hiro
                                     FALSE, TRUE);
431 1 hiro
        gtk_ctree_node_set_row_data(ctree, node, partinfo);
432 1 hiro
433 1 hiro
        return node;
434 1 hiro
}
435 1 hiro
436 1 hiro
static void mimeview_show_message_part(MimeView *mimeview, MimeInfo *partinfo)
437 1 hiro
{
438 1 hiro
        FILE *fp;
439 1 hiro
        const gchar *fname;
440 1 hiro
#if USE_GPGME
441 1 hiro
        MimeInfo *pi;
442 1 hiro
#endif
443 1 hiro
444 1 hiro
        if (!partinfo) return;
445 1 hiro
446 1 hiro
#if USE_GPGME
447 1 hiro
        for (pi = partinfo; pi && !pi->plaintextfile ; pi = pi->parent)
448 1 hiro
                ;
449 1 hiro
        fname = pi ? pi->plaintextfile : mimeview->file;
450 1 hiro
#else
451 1 hiro
        fname = mimeview->file;
452 1 hiro
#endif /* USE_GPGME */
453 1 hiro
        if (!fname) return;
454 1 hiro
455 1 hiro
        if ((fp = fopen(fname, "rb")) == NULL) {
456 1 hiro
                FILE_OP_ERROR(fname, "fopen");
457 1 hiro
                return;
458 1 hiro
        }
459 1 hiro
460 1 hiro
        if (fseek(fp, partinfo->fpos, SEEK_SET) < 0) {
461 1 hiro
                FILE_OP_ERROR(mimeview->file, "fseek");
462 1 hiro
                fclose(fp);
463 1 hiro
                return;
464 1 hiro
        }
465 1 hiro
466 1 hiro
        mimeview_change_view_type(mimeview, MIMEVIEW_TEXT);
467 1 hiro
        textview_show_part(mimeview->textview, partinfo, fp);
468 1 hiro
469 1 hiro
        fclose(fp);
470 1 hiro
}
471 1 hiro
472 1 hiro
static void mimeview_show_image_part(MimeView *mimeview, MimeInfo *partinfo)
473 1 hiro
{
474 1 hiro
        gchar *filename;
475 1 hiro
476 1 hiro
        if (!partinfo) return;
477 1 hiro
478 1 hiro
        filename = procmime_get_tmp_file_name(partinfo);
479 1 hiro
480 1 hiro
        if (procmime_get_part(filename, mimeview->file, partinfo) < 0)
481 1 hiro
                alertpanel_error
482 1 hiro
                        (_("Can't get the part of multipart message."));
483 1 hiro
        else {
484 1 hiro
                mimeview_change_view_type(mimeview, MIMEVIEW_IMAGE);
485 1 hiro
                imageview_show_image(mimeview->imageview, partinfo, filename,
486 1 hiro
                                     prefs_common.resize_image);
487 1 hiro
                unlink(filename);
488 1 hiro
        }
489 1 hiro
490 1 hiro
        g_free(filename);
491 1 hiro
}
492 1 hiro
493 1 hiro
static void mimeview_change_view_type(MimeView *mimeview, MimeViewType type)
494 1 hiro
{
495 1 hiro
        TextView  *textview  = mimeview->textview;
496 1 hiro
        ImageView *imageview = mimeview->imageview;
497 1 hiro
        GList *children;
498 1 hiro
499 1 hiro
        if (mimeview->type == type) return;
500 1 hiro
501 1 hiro
        children = gtk_container_get_children
502 1 hiro
                (GTK_CONTAINER(mimeview->mime_vbox));
503 1 hiro
        if (children) {
504 1 hiro
                gtkut_container_remove(GTK_CONTAINER(mimeview->mime_vbox),
505 1 hiro
                                       GTK_WIDGET(children->data));
506 1 hiro
                g_list_free(children);
507 1 hiro
        }
508 1 hiro
509 1 hiro
        switch (type) {
510 1 hiro
        case MIMEVIEW_IMAGE:
511 1 hiro
                gtk_container_add(GTK_CONTAINER(mimeview->mime_vbox),
512 1 hiro
                                  GTK_WIDGET_PTR(imageview));
513 1 hiro
                break;
514 1 hiro
        case MIMEVIEW_TEXT:
515 1 hiro
                gtk_container_add(GTK_CONTAINER(mimeview->mime_vbox),
516 1 hiro
                                  GTK_WIDGET_PTR(textview));
517 1 hiro
                break;
518 1 hiro
        default:
519 1 hiro
                return;
520 1 hiro
        }
521 1 hiro
522 1 hiro
        mimeview->type = type;
523 1 hiro
}
524 1 hiro
525 1 hiro
static void mimeview_selected(GtkCTree *ctree, GtkCTreeNode *node, gint column,
526 1 hiro
                              MimeView *mimeview)
527 1 hiro
{
528 1 hiro
        MimeInfo *partinfo;
529 1 hiro
530 1 hiro
        if (mimeview->opened == node) return;
531 1 hiro
        mimeview->opened = node;
532 1 hiro
        gtk_ctree_node_moveto(ctree, node, -1, 0.5, 0);
533 1 hiro
534 1 hiro
        partinfo = gtk_ctree_node_get_row_data(ctree, node);
535 1 hiro
        if (!partinfo) return;
536 1 hiro
537 1 hiro
        /* ungrab the mouse event */
538 1 hiro
        if (GTK_WIDGET_HAS_GRAB(ctree)) {
539 1 hiro
                gtk_grab_remove(GTK_WIDGET(ctree));
540 1 hiro
                if (gdk_pointer_is_grabbed())
541 1 hiro
                        gdk_pointer_ungrab(GDK_CURRENT_TIME);
542 1 hiro
        }
543 1 hiro
544 1 hiro
        switch (partinfo->mime_type) {
545 1 hiro
        case MIME_TEXT:
546 1 hiro
        case MIME_TEXT_HTML:
547 1 hiro
        case MIME_MESSAGE_RFC822:
548 1 hiro
        case MIME_MULTIPART:
549 1 hiro
                mimeview_show_message_part(mimeview, partinfo);
550 1 hiro
                break;
551 1 hiro
#if (HAVE_GDK_PIXBUF || HAVE_GDK_IMLIB)
552 1 hiro
        case MIME_IMAGE:
553 1 hiro
                mimeview_show_image_part(mimeview, partinfo);
554 1 hiro
                break;
555 1 hiro
#endif
556 1 hiro
        default:
557 1 hiro
                mimeview_change_view_type(mimeview, MIMEVIEW_TEXT);
558 1 hiro
#if USE_GPGME
559 1 hiro
                if (g_strcasecmp(partinfo->content_type,
560 1 hiro
                                 "application/pgp-signature") == 0)
561 1 hiro
                        textview_show_signature_part(mimeview->textview,
562 1 hiro
                                                     partinfo);
563 1 hiro
                else
564 1 hiro
#endif
565 1 hiro
                        textview_show_mime_part(mimeview->textview, partinfo);
566 1 hiro
                break;
567 1 hiro
        }
568 1 hiro
}
569 1 hiro
570 1 hiro
static void mimeview_start_drag(GtkWidget *widget, gint button,
571 1 hiro
                                GdkEvent *event, MimeView *mimeview)
572 1 hiro
{
573 1 hiro
        GtkTargetList *list;
574 1 hiro
        GdkDragContext *context;
575 1 hiro
        MimeInfo *partinfo;
576 1 hiro
577 1 hiro
        g_return_if_fail(mimeview != NULL);
578 1 hiro
579 1 hiro
        partinfo = mimeview_get_selected_part(mimeview);
580 1 hiro
        if (partinfo->filename == NULL && partinfo->name == NULL) return;
581 1 hiro
582 1 hiro
        list = gtk_target_list_new(mimeview_mime_types, 1);
583 1 hiro
        context = gtk_drag_begin(widget, list,
584 1 hiro
                                 GDK_ACTION_COPY, button, event);
585 1 hiro
        gtk_drag_set_icon_default(context);
586 1 hiro
}
587 1 hiro
588 1 hiro
static gint mimeview_button_pressed(GtkWidget *widget, GdkEventButton *event,
589 1 hiro
                                    MimeView *mimeview)
590 1 hiro
{
591 1 hiro
        GtkCList *clist = GTK_CLIST(widget);
592 1 hiro
        MimeInfo *partinfo;
593 1 hiro
        gint row, column;
594 1 hiro
595 1 hiro
        if (!event) return FALSE;
596 1 hiro
597 1 hiro
        if (event->button == 2 || event->button == 3) {
598 1 hiro
                if (!gtk_clist_get_selection_info(clist, event->x, event->y,
599 1 hiro
                                                  &row, &column))
600 1 hiro
                        return FALSE;
601 1 hiro
                gtk_clist_unselect_all(clist);
602 1 hiro
                gtk_clist_select_row(clist, row, column);
603 1 hiro
                gtkut_clist_set_focus_row(clist, row);
604 1 hiro
        }
605 1 hiro
606 1 hiro
        if (event->button == 2 ||
607 1 hiro
            (event->button == 1 && event->type == GDK_2BUTTON_PRESS)) {
608 1 hiro
                /* call external program for image, audio or html */
609 1 hiro
                mimeview_launch(mimeview);
610 1 hiro
        } else if (event->button == 3) {
611 1 hiro
                partinfo = mimeview_get_selected_part(mimeview);
612 1 hiro
                if (partinfo && (partinfo->mime_type == MIME_TEXT ||
613 1 hiro
                                 partinfo->mime_type == MIME_TEXT_HTML ||
614 1 hiro
                                 partinfo->mime_type == MIME_MESSAGE_RFC822 ||
615 1 hiro
                                 partinfo->mime_type == MIME_IMAGE ||
616 1 hiro
                                 partinfo->mime_type == MIME_MULTIPART))
617 1 hiro
                        menu_set_sensitive(mimeview->popupfactory,
618 1 hiro
                                           "/Display as text", FALSE);
619 1 hiro
                else
620 1 hiro
                        menu_set_sensitive(mimeview->popupfactory,
621 1 hiro
                                           "/Display as text", TRUE);
622 1 hiro
                if (partinfo &&
623 1 hiro
                    partinfo->mime_type == MIME_APPLICATION_OCTET_STREAM)
624 1 hiro
                        menu_set_sensitive(mimeview->popupfactory,
625 1 hiro
                                           "/Open", FALSE);
626 1 hiro
                else
627 1 hiro
                        menu_set_sensitive(mimeview->popupfactory,
628 1 hiro
                                           "/Open", TRUE);
629 1 hiro
#if USE_GPGME
630 1 hiro
                menu_set_sensitive(mimeview->popupfactory,
631 1 hiro
                                   "/Check signature",
632 1 hiro
                                   mimeview_is_signed(mimeview));
633 1 hiro
#endif
634 1 hiro
635 1 hiro
                gtk_menu_popup(GTK_MENU(mimeview->popupmenu),
636 1 hiro
                               NULL, NULL, NULL, NULL,
637 1 hiro
                               event->button, event->time);
638 1 hiro
        }
639 1 hiro
640 1 hiro
#warning FIXME_GTK2 Is it correct?
641 1 hiro
        return FALSE;
642 1 hiro
}
643 1 hiro
644 1 hiro
void mimeview_pass_key_press_event(MimeView *mimeview, GdkEventKey *event)
645 1 hiro
{
646 1 hiro
        mimeview_key_pressed(mimeview->ctree, event, mimeview);
647 1 hiro
}
648 1 hiro
649 1 hiro
#define BREAK_ON_MODIFIER_KEY() \
650 1 hiro
        if ((event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK)) != 0) break
651 1 hiro
652 1 hiro
#warning FIXME_GTK2
653 1 hiro
#if 0
654 1 hiro
#define KEY_PRESS_EVENT_STOP() \
655 1 hiro
        if (gtk_signal_n_emissions_by_name \
656 1 hiro
                (G_OBJECT(ctree), "key_press_event") > 0) { \
657 1 hiro
                gtk_signal_emit_stop_by_name(G_OBJECT(ctree), \
658 1 hiro
                                             "key_press_event"); \
659 1 hiro
        }
660 1 hiro
#else
661 1 hiro
#define KEY_PRESS_EVENT_STOP() \
662 1 hiro
        g_signal_stop_emission_by_name(G_OBJECT(ctree), "key_press_event");
663 1 hiro
#endif
664 1 hiro
665 1 hiro
static gint mimeview_key_pressed(GtkWidget *widget, GdkEventKey *event,
666 1 hiro
                                 MimeView *mimeview)
667 1 hiro
{
668 1 hiro
        SummaryView *summaryview;
669 1 hiro
        GtkCTree *ctree = GTK_CTREE(widget);
670 1 hiro
        GtkCTreeNode *node;
671 1 hiro
672 1 hiro
        if (!event) return FALSE;
673 1 hiro
        if (!mimeview->opened) return FALSE;
674 1 hiro
675 1 hiro
        switch (event->keyval) {
676 1 hiro
        case GDK_space:
677 1 hiro
                if (textview_scroll_page(mimeview->textview, FALSE))
678 1 hiro
                        return TRUE;
679 1 hiro
680 1 hiro
                node = GTK_CTREE_NODE_NEXT(mimeview->opened);
681 1 hiro
                if (node) {
682 1 hiro
                        gtk_sctree_unselect_all(GTK_SCTREE(ctree));
683 1 hiro
                        gtk_sctree_select(GTK_SCTREE(ctree), node);
684 1 hiro
                        return TRUE;
685 1 hiro
                }
686 1 hiro
                break;
687 1 hiro
        case GDK_BackSpace:
688 1 hiro
                textview_scroll_page(mimeview->textview, TRUE);
689 1 hiro
                return TRUE;
690 1 hiro
        case GDK_Return:
691 1 hiro
                textview_scroll_one_line(mimeview->textview,
692 1 hiro
                                         (event->state & GDK_MOD1_MASK) != 0);
693 1 hiro
                return TRUE;
694 1 hiro
        case GDK_n:
695 1 hiro
        case GDK_N:
696 1 hiro
                BREAK_ON_MODIFIER_KEY();
697 1 hiro
                if (!GTK_CTREE_NODE_NEXT(mimeview->opened)) break;
698 1 hiro
                KEY_PRESS_EVENT_STOP();
699 1 hiro
700 1 hiro
                g_signal_emit_by_name(G_OBJECT(ctree), "scroll_vertical",
701 1 hiro
                                      GTK_SCROLL_STEP_FORWARD, 0.0);
702 1 hiro
                return TRUE;
703 1 hiro
        case GDK_p:
704 1 hiro
        case GDK_P:
705 1 hiro
                BREAK_ON_MODIFIER_KEY();
706 1 hiro
                if (!GTK_CTREE_NODE_PREV(mimeview->opened)) break;
707 1 hiro
                KEY_PRESS_EVENT_STOP();
708 1 hiro
709 1 hiro
                g_signal_emit_by_name(G_OBJECT(ctree), "scroll_vertical",
710 1 hiro
                                      GTK_SCROLL_STEP_BACKWARD, 0.0);
711 1 hiro
                return TRUE;
712 1 hiro
        case GDK_y:
713 1 hiro
                BREAK_ON_MODIFIER_KEY();
714 1 hiro
                KEY_PRESS_EVENT_STOP();
715 1 hiro
                mimeview_save_as(mimeview);
716 1 hiro
                return TRUE;
717 1 hiro
        case GDK_t:
718 1 hiro
                BREAK_ON_MODIFIER_KEY();
719 1 hiro
                KEY_PRESS_EVENT_STOP();
720 1 hiro
                mimeview_display_as_text(mimeview);
721 1 hiro
                return TRUE;
722 1 hiro
        case GDK_l:
723 1 hiro
                BREAK_ON_MODIFIER_KEY();
724 1 hiro
                KEY_PRESS_EVENT_STOP();
725 1 hiro
                mimeview_launch(mimeview);
726 1 hiro
                return TRUE;
727 1 hiro
        default:
728 1 hiro
                break;
729 1 hiro
        }
730 1 hiro
731 1 hiro
        if (!mimeview->messageview->mainwin) return FALSE;
732 1 hiro
        summaryview = mimeview->messageview->mainwin->summaryview;
733 1 hiro
        summary_pass_key_press_event(summaryview, event);
734 1 hiro
        return TRUE;
735 1 hiro
}
736 1 hiro
737 1 hiro
static void mimeview_drag_data_get(GtkWidget            *widget,
738 1 hiro
                                   GdkDragContext   *drag_context,
739 1 hiro
                                   GtkSelectionData *selection_data,
740 1 hiro
                                   guint             info,
741 1 hiro
                                   guint             time,
742 1 hiro
                                   MimeView            *mimeview)
743 1 hiro
{
744 1 hiro
        gchar *filename, *uriname;
745 1 hiro
        const gchar *bname;
746 1 hiro
        MimeInfo *partinfo;
747 1 hiro
748 1 hiro
        if (!mimeview->opened) return;
749 1 hiro
        if (!mimeview->file) return;
750 1 hiro
751 1 hiro
        partinfo = mimeview_get_selected_part(mimeview);
752 1 hiro
        if (!partinfo) return;
753 1 hiro
        if (!partinfo->filename && !partinfo->name) return;
754 1 hiro
755 1 hiro
        filename = partinfo->filename ? partinfo->filename : partinfo->name;
756 1 hiro
        bname = g_basename(filename);
757 1 hiro
        if (*bname == '\0') return;
758 1 hiro
759 1 hiro
        filename = g_strconcat(get_mime_tmp_dir(), G_DIR_SEPARATOR_S,
760 1 hiro
                               bname, NULL);
761 1 hiro
762 1 hiro
        if (procmime_get_part(filename, mimeview->file, partinfo) < 0)
763 1 hiro
                alertpanel_error
764 1 hiro
                        (_("Can't save the part of multipart message."));
765 1 hiro
766 1 hiro
        uriname = g_strconcat("file://", filename, NULL);
767 1 hiro
        gtk_selection_data_set(selection_data, selection_data->target, 8,
768 1 hiro
                               uriname, strlen(uriname));
769 1 hiro
770 1 hiro
        g_free(uriname);
771 1 hiro
        g_free(filename);
772 1 hiro
}
773 1 hiro
774 1 hiro
static void mimeview_display_as_text(MimeView *mimeview)
775 1 hiro
{
776 1 hiro
        MimeInfo *partinfo;
777 1 hiro
778 1 hiro
        if (!mimeview->opened) return;
779 1 hiro
780 1 hiro
        partinfo = mimeview_get_selected_part(mimeview);
781 1 hiro
        g_return_if_fail(partinfo != NULL);
782 1 hiro
        mimeview_show_message_part(mimeview, partinfo);
783 1 hiro
}
784 1 hiro
785 1 hiro
static void mimeview_save_as(MimeView *mimeview)
786 1 hiro
{
787 1 hiro
        gchar *filename;
788 1 hiro
        gchar *defname = NULL;
789 1 hiro
        MimeInfo *partinfo;
790 1 hiro
791 1 hiro
        if (!mimeview->opened) return;
792 1 hiro
        if (!mimeview->file) return;
793 1 hiro
794 1 hiro
        partinfo = mimeview_get_selected_part(mimeview);
795 1 hiro
        g_return_if_fail(partinfo != NULL);
796 1 hiro
797 1 hiro
        if (partinfo->filename)
798 1 hiro
                defname = partinfo->filename;
799 1 hiro
        else if (partinfo->name) {
800 1 hiro
                Xstrdup_a(defname, partinfo->name, return);
801 1 hiro
                subst_for_filename(defname);
802 1 hiro
        }
803 1 hiro
804 1 hiro
        filename = filesel_select_file(_("Save as"), defname);
805 1 hiro
        if (!filename) return;
806 1 hiro
        if (is_file_exist(filename)) {
807 1 hiro
                AlertValue aval;
808 1 hiro
809 1 hiro
                aval = alertpanel(_("Overwrite"),
810 1 hiro
                                  _("Overwrite existing file?"),
811 36 hiro
                                  GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL);
812 1 hiro
                if (G_ALERTDEFAULT != aval) return;
813 1 hiro
        }
814 1 hiro
815 1 hiro
        if (procmime_get_part(filename, mimeview->file, partinfo) < 0)
816 1 hiro
                alertpanel_error
817 1 hiro
                        (_("Can't save the part of multipart message."));
818 1 hiro
}
819 1 hiro
820 1 hiro
static void mimeview_launch(MimeView *mimeview)
821 1 hiro
{
822 1 hiro
        MimeInfo *partinfo;
823 1 hiro
        gchar *filename;
824 1 hiro
825 1 hiro
        if (!mimeview->opened) return;
826 1 hiro
        if (!mimeview->file) return;
827 1 hiro
828 1 hiro
        partinfo = mimeview_get_selected_part(mimeview);
829 1 hiro
        g_return_if_fail(partinfo != NULL);
830 1 hiro
831 1 hiro
        filename = procmime_get_tmp_file_name(partinfo);
832 1 hiro
833 1 hiro
        if (procmime_get_part(filename, mimeview->file, partinfo) < 0)
834 1 hiro
                alertpanel_error
835 1 hiro
                        (_("Can't save the part of multipart message."));
836 1 hiro
        else
837 1 hiro
                mimeview_view_file(filename, partinfo, NULL);
838 1 hiro
839 1 hiro
        g_free(filename);
840 1 hiro
}
841 1 hiro
842 1 hiro
static void mimeview_open_with(MimeView *mimeview)
843 1 hiro
{
844 1 hiro
        MimeInfo *partinfo;
845 1 hiro
        gchar *filename;
846 1 hiro
        gchar *cmd;
847 1 hiro
848 1 hiro
        if (!mimeview->opened) return;
849 1 hiro
        if (!mimeview->file) return;
850 1 hiro
851 1 hiro
        partinfo = mimeview_get_selected_part(mimeview);
852 1 hiro
        g_return_if_fail(partinfo != NULL);
853 1 hiro
854 1 hiro
        filename = procmime_get_tmp_file_name(partinfo);
855 1 hiro
856 1 hiro
        if (procmime_get_part(filename, mimeview->file, partinfo) < 0) {
857 1 hiro
                alertpanel_error
858 1 hiro
                        (_("Can't save the part of multipart message."));
859 1 hiro
                g_free(filename);
860 1 hiro
                return;
861 1 hiro
        }
862 1 hiro
863 1 hiro
        if (!prefs_common.mime_open_cmd_history)
864 1 hiro
                prefs_common.mime_open_cmd_history =
865 1 hiro
                        add_history(NULL, prefs_common.mime_open_cmd);
866 1 hiro
867 1 hiro
        cmd = input_dialog_combo
868 1 hiro
                (_("Open with"),
869 1 hiro
                 _("Enter the command line to open file:\n"
870 1 hiro
                   "(`%s' will be replaced with file name)"),
871 1 hiro
                 prefs_common.mime_open_cmd,
872 1 hiro
                 prefs_common.mime_open_cmd_history,
873 1 hiro
                 TRUE);
874 1 hiro
        if (cmd) {
875 1 hiro
                mimeview_view_file(filename, partinfo, cmd);
876 1 hiro
                g_free(prefs_common.mime_open_cmd);
877 1 hiro
                prefs_common.mime_open_cmd = cmd;
878 1 hiro
                prefs_common.mime_open_cmd_history =
879 1 hiro
                        add_history(prefs_common.mime_open_cmd_history, cmd);
880 1 hiro
        }
881 1 hiro
882 1 hiro
        g_free(filename);
883 1 hiro
}
884 1 hiro
885 1 hiro
static void mimeview_view_file(const gchar *filename, MimeInfo *partinfo,
886 1 hiro
                               const gchar *cmdline)
887 1 hiro
{
888 1 hiro
        static gchar *default_image_cmdline = "display '%s'";
889 1 hiro
        static gchar *default_audio_cmdline = "play '%s'";
890 1 hiro
        static gchar *default_html_cmdline = DEFAULT_BROWSER_CMD;
891 1 hiro
        static gchar *mime_cmdline = "metamail -d -b -x -c %s '%s'";
892 1 hiro
        gchar buf[1024];
893 1 hiro
        gchar m_buf[1024];
894 1 hiro
        const gchar *cmd;
895 1 hiro
        const gchar *def_cmd;
896 1 hiro
        const gchar *p;
897 1 hiro
898 1 hiro
        if (cmdline) {
899 1 hiro
                cmd = cmdline;
900 1 hiro
                def_cmd = NULL;
901 1 hiro
        } else if (MIME_APPLICATION_OCTET_STREAM == partinfo->mime_type) {
902 1 hiro
                return;
903 1 hiro
        } else if (MIME_IMAGE == partinfo->mime_type) {
904 1 hiro
                cmd = prefs_common.mime_image_viewer;
905 1 hiro
                def_cmd = default_image_cmdline;
906 1 hiro
        } else if (MIME_AUDIO == partinfo->mime_type) {
907 1 hiro
                cmd = prefs_common.mime_audio_player;
908 1 hiro
                def_cmd = default_audio_cmdline;
909 1 hiro
        } else if (MIME_TEXT_HTML == partinfo->mime_type) {
910 1 hiro
                cmd = prefs_common.uri_cmd;
911 1 hiro
                def_cmd = default_html_cmdline;
912 1 hiro
        } else {
913 1 hiro
                g_snprintf(m_buf, sizeof(m_buf), mime_cmdline,
914 1 hiro
                           partinfo->content_type, "%s");
915 1 hiro
                cmd = m_buf;
916 1 hiro
                def_cmd = NULL;
917 1 hiro
        }
918 1 hiro
919 1 hiro
        if (cmd && (p = strchr(cmd, '%')) && *(p + 1) == 's' &&
920 1 hiro
            !strchr(p + 2, '%'))
921 1 hiro
                g_snprintf(buf, sizeof(buf), cmd, filename);
922 1 hiro
        else {
923 1 hiro
                if (cmd)
924 1 hiro
                        g_warning(_("MIME viewer command line is invalid: `%s'"), cmd);
925 1 hiro
                if (def_cmd)
926 1 hiro
                        g_snprintf(buf, sizeof(buf), def_cmd, filename);
927 1 hiro
                else
928 1 hiro
                        return;
929 1 hiro
        }
930 1 hiro
931 1 hiro
        execute_command_line(buf, TRUE);
932 1 hiro
}
933 1 hiro
934 1 hiro
#if USE_GPGME
935 1 hiro
static void update_node_name(GtkCTree *ctree, GtkCTreeNode *node,
936 1 hiro
                             gpointer data)
937 1 hiro
{
938 1 hiro
        MimeInfo *partinfo;
939 1 hiro
        gchar *part_name;
940 1 hiro
941 1 hiro
        partinfo = gtk_ctree_node_get_row_data(ctree, node);
942 1 hiro
        g_return_if_fail(partinfo != NULL);
943 1 hiro
944 1 hiro
        part_name = get_part_name(partinfo);
945 1 hiro
        gtk_ctree_node_set_text(ctree, node, COL_NAME, part_name);
946 1 hiro
}
947 1 hiro
948 1 hiro
static void mimeview_update_names(MimeView *mimeview)
949 1 hiro
{
950 1 hiro
        GtkCTree *ctree = GTK_CTREE(mimeview->ctree);
951 1 hiro
952 1 hiro
        gtk_ctree_pre_recursive(ctree, NULL, update_node_name, NULL);
953 1 hiro
}
954 1 hiro
955 1 hiro
static void mimeview_update_signature_info(MimeView *mimeview)
956 1 hiro
{
957 1 hiro
        MimeInfo *partinfo;
958 1 hiro
959 1 hiro
        if (!mimeview) return;
960 1 hiro
        if (!mimeview->opened) return;
961 1 hiro
962 1 hiro
        partinfo = mimeview_get_selected_part(mimeview);
963 1 hiro
        if (!partinfo) return;
964 1 hiro
965 1 hiro
        if (g_strcasecmp(partinfo->content_type,
966 1 hiro
                         "application/pgp-signature") == 0) {
967 1 hiro
                mimeview_change_view_type(mimeview, MIMEVIEW_TEXT);
968 1 hiro
                textview_show_signature_part(mimeview->textview, partinfo);
969 1 hiro
        }
970 1 hiro
}
971 1 hiro
972 1 hiro
static void mimeview_check_signature(MimeView *mimeview)
973 1 hiro
{
974 1 hiro
        MimeInfo *mimeinfo;
975 1 hiro
        FILE *fp;
976 1 hiro
977 1 hiro
        g_return_if_fail (mimeview_is_signed(mimeview));
978 1 hiro
979 1 hiro
        mimeinfo = mimeview_get_selected_part(mimeview);
980 1 hiro
        g_return_if_fail(mimeinfo != NULL);
981 1 hiro
        g_return_if_fail(mimeview->file != NULL);
982 1 hiro
983 1 hiro
        while (mimeinfo->parent)
984 1 hiro
                mimeinfo = mimeinfo->parent;
985 1 hiro
986 1 hiro
        if ((fp = fopen(mimeview->file, "rb")) == NULL) {
987 1 hiro
                FILE_OP_ERROR(mimeview->file, "fopen");
988 1 hiro
                return;
989 1 hiro
        }
990 1 hiro
991 1 hiro
        rfc2015_check_signature(mimeinfo, fp);
992 1 hiro
        fclose(fp);
993 1 hiro
994 1 hiro
        mimeview_update_names(mimeview);
995 1 hiro
        mimeview_update_signature_info(mimeview);
996 1 hiro
997 1 hiro
        textview_show_message(mimeview->messageview->textview, mimeinfo,
998 1 hiro
                              mimeview->file);
999 1 hiro
}
1000 1 hiro
#endif /* USE_GPGME */