o fix another memory leak reported by Martin Kluge (see "[ 599568 ] Small Memory...
[claws.git] / src / messageview.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2002 Hiroyuki Yamamoto
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #include "defs.h"
21
22 #include <glib.h>
23 #include <gdk/gdkkeysyms.h>
24 #include <gtk/gtkvbox.h>
25 #include <gtk/gtkcontainer.h>
26 #include <gtk/gtkeditable.h>
27 #include <gtk/gtkwindow.h>
28 #include <gtk/gtktext.h>
29 #include <stdio.h>
30 #include <ctype.h>
31 #include <string.h>
32
33 #include "intl.h"
34 #include "main.h"
35 #include "messageview.h"
36 #include "headerview.h"
37 #include "textview.h"
38 #include "imageview.h"
39 #include "mimeview.h"
40 #include "procmsg.h"
41 #include "procheader.h"
42 #include "procmime.h"
43 #include "prefs_common.h"
44 #include "gtkutils.h"
45 #include "utils.h"
46 #include "rfc2015.h"
47 #include "account.h"
48 #include "alertpanel.h"
49 #include "send.h"
50 #include "pgptext.h"
51 #include "menu.h"
52
53 static void messageview_change_view_type(MessageView    *messageview,
54                                          MessageType     type);
55 static void messageview_destroy_cb      (GtkWidget      *widget,
56                                          MessageView    *messageview);
57 static void messageview_size_allocate_cb(GtkWidget      *widget,
58                                          GtkAllocation  *allocation);
59 static void key_pressed                 (GtkWidget      *widget,
60                                          GdkEventKey    *event,
61                                          MessageView    *messageview);
62
63 static void return_receipt_show         (NoticeView     *noticeview, 
64                                          MsgInfo        *msginfo);      
65 static void return_receipt_send_clicked (NoticeView     *noticeview, 
66                                          MsgInfo        *msginfo);
67
68 static PrefsAccount *select_account_from_list
69                                         (GList          *ac_list);
70
71 MessageView *messageview_create(MainWindow *mainwin)
72 {
73         MessageView *messageview;
74         GtkWidget *vbox;
75         HeaderView *headerview;
76         TextView *textview;
77         ImageView *imageview;
78         MimeView *mimeview;
79         NoticeView *noticeview;
80
81         debug_print("Creating message view...\n");
82         messageview = g_new0(MessageView, 1);
83
84         messageview->type = MVIEW_TEXT;
85
86         headerview = headerview_create();
87
88         noticeview = noticeview_create(mainwin);
89
90         textview = textview_create();
91         textview->messageview = messageview;
92
93         imageview = imageview_create();
94         imageview->messageview = messageview;
95
96         mimeview = mimeview_create();
97         mimeview->textview = textview_create();
98         mimeview->textview->messageview = messageview;
99         mimeview->imageview = imageview;
100         mimeview->messageview = messageview;
101
102         vbox = gtk_vbox_new(FALSE, 0);
103         gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET_PTR(headerview),
104                            FALSE, FALSE, 0);
105         gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET_PTR(noticeview),
106                            FALSE, FALSE, 0);
107         gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET_PTR(textview),
108                            TRUE, TRUE, 0);
109
110         /* to remove without destroyed */
111         gtk_widget_ref(GTK_WIDGET_PTR(textview));
112         gtk_widget_ref(GTK_WIDGET_PTR(imageview));
113         gtk_widget_ref(GTK_WIDGET_PTR(mimeview));
114         gtk_widget_ref(GTK_WIDGET_PTR(mimeview->textview));
115
116         messageview->vbox       = vbox;
117         messageview->new_window = FALSE;
118         messageview->window     = NULL;
119         messageview->headerview = headerview;
120         messageview->textview   = textview;
121         messageview->imageview  = imageview;
122         messageview->mimeview   = mimeview;
123         messageview->noticeview = noticeview;
124
125         return messageview;
126 }
127
128 MessageView *messageview_create_with_new_window(MainWindow *mainwin)
129 {
130         GtkWidget *window;
131         MessageView *msgview;
132
133         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
134         gtk_window_set_title(GTK_WINDOW(window), _("Sylpheed - Message View"));
135         gtk_window_set_wmclass(GTK_WINDOW(window), "message_view", "Sylpheed");
136         gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, FALSE);
137         gtk_widget_set_usize(window, prefs_common.msgwin_width,
138                              prefs_common.msgwin_height);
139
140         msgview = messageview_create(mainwin);
141
142         gtk_signal_connect(GTK_OBJECT(window), "size_allocate",
143                            GTK_SIGNAL_FUNC(messageview_size_allocate_cb),
144                            msgview);
145         gtk_signal_connect(GTK_OBJECT(window), "destroy",
146                            GTK_SIGNAL_FUNC(messageview_destroy_cb), msgview);
147         gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
148                            GTK_SIGNAL_FUNC(key_pressed), msgview);
149
150         gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET_PTR(msgview));
151         gtk_widget_grab_focus(msgview->textview->text);
152         gtk_widget_show_all(window);
153
154         msgview->new_window = TRUE;
155         msgview->window = window;
156         msgview->visible = TRUE;
157
158         messageview_init(msgview);
159
160         return msgview;
161 }
162
163 void messageview_init(MessageView *messageview)
164 {
165         headerview_init(messageview->headerview);
166         textview_init(messageview->textview);
167         imageview_init(messageview->imageview);
168         mimeview_init(messageview->mimeview);
169         /*messageview_set_font(messageview);*/
170
171         noticeview_hide(messageview->noticeview);
172 }
173
174 static void notification_convert_header(gchar *dest, gint len, 
175                                         const gchar *src_,
176                                         gint header_len)
177 {
178         char *src;
179
180         g_return_if_fail(src_ != NULL);
181         g_return_if_fail(dest != NULL);
182
183         if (len < 1) return;
184
185         Xstrndup_a(src, src_, len, return);
186
187         remove_return(src);
188
189         if (is_ascii_str(src)) {
190                 strncpy2(dest, src, len);
191                 dest[len - 1] = '\0';
192                 return;
193         } else
194                 conv_encode_header(dest, len, src, header_len);
195 }
196
197 static gint disposition_notification_queue(PrefsAccount * account,
198                                            gchar * to, const gchar *file)
199 {
200         FolderItem *queue;
201         gchar *tmp;
202         FILE *fp, *src_fp;
203         gchar buf[BUFFSIZE];
204         gint num;
205
206         debug_print("queueing message...\n");
207         g_return_val_if_fail(account != NULL, -1);
208
209         tmp = g_strdup_printf("%s%cqueue.%d", g_get_tmp_dir(),
210                               G_DIR_SEPARATOR, (gint)file);
211         if ((fp = fopen(tmp, "wb")) == NULL) {
212                 FILE_OP_ERROR(tmp, "fopen");
213                 g_free(tmp);
214                 return -1;
215         }
216         if ((src_fp = fopen(file, "rb")) == NULL) {
217                 FILE_OP_ERROR(file, "fopen");
218                 fclose(fp);
219                 unlink(tmp);
220                 g_free(tmp);
221                 return -1;
222         }
223         if (change_file_mode_rw(fp, tmp) < 0) {
224                 FILE_OP_ERROR(tmp, "chmod");
225                 g_warning(_("can't change file mode\n"));
226         }
227
228         /* queueing variables */
229         fprintf(fp, "AF:\n");
230         fprintf(fp, "NF:0\n");
231         fprintf(fp, "PS:10\n");
232         fprintf(fp, "SRH:1\n");
233         fprintf(fp, "SFN:\n");
234         fprintf(fp, "DSR:\n");
235         fprintf(fp, "MID:\n");
236         fprintf(fp, "CFG:\n");
237         fprintf(fp, "PT:0\n");
238         fprintf(fp, "S:%s\n", account->address);
239         fprintf(fp, "RQ:\n");
240         if (account->smtp_server)
241                 fprintf(fp, "SSV:%s\n", account->smtp_server);
242         else
243                 fprintf(fp, "SSV:\n");
244         if (account->nntp_server)
245                 fprintf(fp, "NSV:%s\n", account->nntp_server);
246         else
247                 fprintf(fp, "NSV:\n");
248         fprintf(fp, "SSH:\n");
249         fprintf(fp, "R:<%s>", to);
250         fprintf(fp, "\n");
251         fprintf(fp, "\n");
252
253         while (fgets(buf, sizeof(buf), src_fp) != NULL) {
254                 if (fputs(buf, fp) == EOF) {
255                         FILE_OP_ERROR(tmp, "fputs");
256                         fclose(fp);
257                         fclose(src_fp);
258                         unlink(tmp);
259                         g_free(tmp);
260                         return -1;
261                 }
262         }
263
264         fclose(src_fp);
265         if (fclose(fp) == EOF) {
266                 FILE_OP_ERROR(tmp, "fclose");
267                 unlink(tmp);
268                 g_free(tmp);
269                 return -1;
270         }
271
272         queue = folder_get_default_queue();
273         if ((num = folder_item_add_msg(queue, tmp, TRUE)) < 0) {
274                 g_warning(_("can't queue the message\n"));
275                 unlink(tmp);
276                 g_free(tmp);
277                 return -1;
278         }
279         g_free(tmp);
280
281         folderview_update_item(queue, TRUE);
282
283         return 0;
284 }
285
286 static gint disposition_notification_send(MsgInfo       *msginfo)
287 {
288         gchar buf[BUFFSIZE];
289         gchar tmp[MAXPATHLEN + 1];
290         FILE *fp;
291         GSList *to_list;
292         GList *ac_list;
293         PrefsAccount *account;
294         gint ok;
295         gchar *to;
296
297         if ((!msginfo->returnreceiptto) && 
298             (!msginfo->dispositionnotificationto)) 
299                 return -1;
300
301         /* RFC2298: Test for Return-Path */
302         if (msginfo->dispositionnotificationto)
303                 to = msginfo->dispositionnotificationto;
304         else
305                 to = msginfo->returnreceiptto;
306
307         ok = get_header_from_msginfo(msginfo, buf, sizeof(buf),
308                                 "Return-Path:");
309         if (ok == 0) {
310                 gchar *to_addr = g_strdup(to);
311                 extract_address(to_addr);
312                 extract_address(buf);
313                 ok = strcmp(to_addr, buf);
314                 g_free(to_addr);
315         } else {
316                 strncpy(buf, _("<No Return-Path found>"), 
317                                 sizeof(buf));
318         }
319         
320         if (ok != 0) {
321                 AlertValue val;
322                 gchar *message;
323                 message = g_strdup_printf(
324                                  _("The notification address to which the "
325                                    "return receipt is to be sent\n"
326                                    "does not correspond to the return path:\n"
327                                    "Notification address: %s\n"
328                                    "Return path: %s\n"
329                                    "It is advised to not to send the return "
330                                    "receipt."), to, buf);
331                 val = alertpanel(_("Warning"), message, _("Send"),
332                                 _("+Don't Send"), NULL);
333                 if (val != G_ALERTDEFAULT)
334                         return -1;
335         }
336
337         ac_list = account_find_all_from_address(NULL, msginfo->to);
338         ac_list = account_find_all_from_address(ac_list, msginfo->cc);
339
340         if (ac_list == NULL) {
341                 alertpanel_error(_("This message is asking for a return "
342                                    "receipt notification\n"
343                                    "but according to its 'To:' and 'CC:' "
344                                    "headers it was not\nofficially addressed "
345                                    "to you.\n"
346                                    "Receipt notification cancelled."));
347                 return -1;
348         }
349
350         if (g_list_length(ac_list) > 1)
351                 account = select_account_from_list(ac_list);
352         else
353                 account = (PrefsAccount *) ac_list->data;
354         g_list_free(ac_list);
355
356         if (account == NULL)
357                 return -1;
358
359         /* write to temporary file */
360         g_snprintf(tmp, sizeof(tmp), "%s%ctmpmsg%d",
361                    get_rc_dir(), G_DIR_SEPARATOR, (gint)msginfo);
362
363         if ((fp = fopen(tmp, "wb")) == NULL) {
364                 FILE_OP_ERROR(tmp, "fopen");
365                 return -1;
366         }
367
368         /* chmod for security */
369         if (change_file_mode_rw(fp, tmp) < 0) {
370                 FILE_OP_ERROR(tmp, "chmod");
371                 g_warning(_("can't change file mode\n"));
372         }
373
374         /* Date */
375         get_rfc822_date(buf, sizeof(buf));
376         fprintf(fp, "Date: %s\n", buf);
377
378         /* From */
379         if (account->name && *account->name) {
380                 notification_convert_header
381                         (buf, sizeof(buf), account->name,
382                          strlen("From: "));
383                 fprintf(fp, "From: %s <%s>\n", buf, account->address);
384         } else
385                 fprintf(fp, "From: %s\n", account->address);
386
387         fprintf(fp, "To: %s\n", to);
388
389         /* Subject */
390         notification_convert_header(buf, sizeof(buf), msginfo->subject,
391                                     strlen("Subject: "));
392         fprintf(fp, "Subject: Disposition notification: %s\n", buf);
393
394         if (fclose(fp) == EOF) {
395                 FILE_OP_ERROR(tmp, "fclose");
396                 unlink(tmp);
397                 return -1;
398         }
399
400         to_list = address_list_append(NULL, to);
401         ok = send_message(tmp, account, to_list);
402         
403         if (ok < 0) {
404                 if (prefs_common.queue_msg) {
405                         AlertValue val;
406                         
407                         val = alertpanel
408                                 (_("Queueing"),
409                                  _("Error occurred while sending the notification.\n"
410                                    "Put this notification into queue folder?"),
411                                  _("OK"), _("Cancel"), NULL);
412                         if (G_ALERTDEFAULT == val) {
413                                 ok = disposition_notification_queue(account, to, tmp);
414                                 if (ok < 0)
415                                         alertpanel_error(_("Can't queue the notification."));
416                         }
417                 } else
418                         alertpanel_error(_("Error occurred while sending the notification."));
419         }
420
421         if (unlink(tmp) < 0) FILE_OP_ERROR(tmp, "unlink");
422
423         return ok;
424 }
425
426 void messageview_show(MessageView *messageview, MsgInfo *msginfo,
427                       gboolean all_headers)
428 {
429         FILE *fp;
430         gchar *file;
431         MimeInfo *mimeinfo;
432         MsgInfo *tmpmsginfo;
433
434         g_return_if_fail(msginfo != NULL);
435
436 #if USE_GPGME
437         if ((fp = procmsg_open_message_decrypted(msginfo, &mimeinfo)) == NULL)
438                 return;
439 #else /* !USE_GPGME */
440         if ((fp = procmsg_open_message(msginfo)) == NULL) return;
441         mimeinfo = procmime_scan_mime_header(fp);
442 #endif /* USE_GPGME */
443         fclose(fp);
444         if (!mimeinfo) return;
445
446         file = procmsg_get_message_file_path(msginfo);
447         if (!file) {
448                 g_warning(_("can't get message file path.\n"));
449                 procmime_mimeinfo_free(mimeinfo);
450                 return;
451         }
452
453         tmpmsginfo = procheader_parse_file(file, msginfo->flags, TRUE, TRUE);
454
455         headerview_show(messageview->headerview, tmpmsginfo);
456         procmsg_msginfo_free(tmpmsginfo);
457
458         textview_set_all_headers(messageview->textview, all_headers);
459         textview_set_all_headers(messageview->mimeview->textview, all_headers);
460
461         if (mimeinfo->mime_type != MIME_TEXT &&
462             mimeinfo->mime_type != MIME_TEXT_HTML) {
463                 messageview_change_view_type(messageview, MVIEW_MIME);
464                 mimeview_show_message(messageview->mimeview, mimeinfo, file);
465         } else {
466                 messageview_change_view_type(messageview, MVIEW_TEXT);
467                 textview_show_message(messageview->textview, mimeinfo, file);
468                 procmime_mimeinfo_free(mimeinfo);
469         }
470
471         if (MSG_IS_RETRCPT_PENDING(msginfo->flags))
472                 return_receipt_show(messageview->noticeview, msginfo);
473         else 
474                 noticeview_hide(messageview->noticeview);
475
476         g_free(file);
477 }
478
479 static void messageview_change_view_type(MessageView *messageview,
480                                          MessageType type)
481 {
482         TextView *textview = messageview->textview;
483         MimeView *mimeview = messageview->mimeview;
484
485         if (messageview->type == type) return;
486
487         if (type == MVIEW_MIME) {
488                 gtkut_container_remove
489                         (GTK_CONTAINER(GTK_WIDGET_PTR(messageview)),
490                          GTK_WIDGET_PTR(textview));
491                 gtk_box_pack_start(GTK_BOX(messageview->vbox),
492                                    GTK_WIDGET_PTR(mimeview), TRUE, TRUE, 0);
493                 gtk_container_add(GTK_CONTAINER(mimeview->vbox),
494                                   GTK_WIDGET_PTR(textview));
495         } else if (type == MVIEW_TEXT) {
496                 gtkut_container_remove
497                         (GTK_CONTAINER(GTK_WIDGET_PTR(messageview)),
498                          GTK_WIDGET_PTR(mimeview));
499
500                 if (mimeview->vbox == GTK_WIDGET_PTR(textview)->parent)
501                         gtkut_container_remove(GTK_CONTAINER(mimeview->vbox),
502                                                GTK_WIDGET_PTR(textview));
503
504                 gtk_box_pack_start(GTK_BOX(messageview->vbox),
505                                    GTK_WIDGET_PTR(textview), TRUE, TRUE, 0);
506         } else
507                 return;
508
509         messageview->type = type;
510 }
511
512 void messageview_clear(MessageView *messageview)
513 {
514         messageview_change_view_type(messageview, MVIEW_TEXT);
515         headerview_clear(messageview->headerview);
516         textview_clear(messageview->textview);
517         imageview_clear(messageview->imageview);
518         noticeview_hide(messageview->noticeview);
519 }
520
521 void messageview_destroy(MessageView *messageview)
522 {
523         GtkWidget *textview  = GTK_WIDGET_PTR(messageview->textview);
524         GtkWidget *imageview = GTK_WIDGET_PTR(messageview->imageview);
525         GtkWidget *mimeview  = GTK_WIDGET_PTR(messageview->mimeview);
526
527         headerview_destroy(messageview->headerview);
528         textview_destroy(messageview->textview);
529         imageview_destroy(messageview->imageview);
530         mimeview_destroy(messageview->mimeview);
531         noticeview_destroy(messageview->noticeview);
532
533         g_free(messageview);
534
535         gtk_widget_unref(textview);
536         gtk_widget_unref(imageview);
537         gtk_widget_unref(mimeview);
538 }
539
540 void messageview_quote_color_set(void)
541 {
542 }
543
544 void messageview_set_font(MessageView *messageview)
545 {
546         textview_set_font(messageview->textview, NULL);
547 }
548
549 TextView *messageview_get_current_textview(MessageView *messageview)
550 {
551         TextView *text = NULL;
552
553         if (messageview->type == MVIEW_TEXT)
554                 text = messageview->textview;
555         else if (messageview->type == MVIEW_MIME) {
556                 if (gtk_notebook_get_current_page
557                         (GTK_NOTEBOOK(messageview->mimeview->notebook)) == 0)
558                         text = messageview->textview;
559                 else if (messageview->mimeview->type == MIMEVIEW_TEXT)
560                         text = messageview->mimeview->textview;
561         }
562
563         return text;
564 }
565
566 void messageview_copy_clipboard(MessageView *messageview)
567 {
568         TextView *text;
569
570         text = messageview_get_current_textview(messageview);
571         if (text)
572                 gtk_editable_copy_clipboard(GTK_EDITABLE(text->text));
573 }
574
575 void messageview_select_all(MessageView *messageview)
576 {
577         TextView *text;
578
579         text = messageview_get_current_textview(messageview);
580         if (text)
581                 gtk_editable_select_region(GTK_EDITABLE(text->text), 0, -1);
582 }
583
584 void messageview_set_position(MessageView *messageview, gint pos)
585 {
586         textview_set_position(messageview->textview, pos);
587 }
588
589 gboolean messageview_search_string(MessageView *messageview, const gchar *str,
590                                    gboolean case_sens)
591 {
592         return textview_search_string(messageview->textview, str, case_sens);
593         return FALSE;
594 }
595
596 gboolean messageview_search_string_backward(MessageView *messageview,
597                                             const gchar *str,
598                                             gboolean case_sens)
599 {
600         return textview_search_string_backward(messageview->textview,
601                                                str, case_sens);
602         return FALSE;
603 }
604
605 gboolean messageview_is_visible(MessageView *messageview)
606 {
607         return messageview->visible;
608 }
609
610 static void messageview_destroy_cb(GtkWidget *widget, MessageView *messageview)
611 {
612         messageview_destroy(messageview);
613 }
614
615 static void messageview_size_allocate_cb(GtkWidget *widget,
616                                          GtkAllocation *allocation)
617 {
618         g_return_if_fail(allocation != NULL);
619
620         prefs_common.msgwin_width  = allocation->width;
621         prefs_common.msgwin_height = allocation->height;
622 }
623
624 static void key_pressed(GtkWidget *widget, GdkEventKey *event,
625                         MessageView *messageview)
626 {
627         if (event && event->keyval == GDK_Escape && messageview->window)
628                 gtk_widget_destroy(messageview->window);
629 }
630
631 void messageview_toggle_view_real(MessageView *messageview)
632 {
633         MainWindow *mainwin = messageview->mainwin;
634         union CompositeWin *cwin = &mainwin->win;
635         GtkWidget *vpaned = NULL;
636         GtkWidget *container = NULL;
637         GtkItemFactory *ifactory =gtk_item_factory_from_widget(mainwin->menubar);
638         
639         switch (mainwin->type) {
640         case SEPARATE_NONE:
641                 vpaned = cwin->sep_none.vpaned;
642                 container = cwin->sep_none.hpaned;
643                 break;
644         case SEPARATE_FOLDER:
645                 vpaned = cwin->sep_folder.vpaned;
646                 container = mainwin->vbox_body;
647                 break;
648         case SEPARATE_MESSAGE:
649         case SEPARATE_BOTH:
650                 return;
651         }
652
653         if (vpaned->parent != NULL) {
654                 gtk_widget_ref(vpaned);
655                 gtkut_container_remove(GTK_CONTAINER(container), vpaned);
656                 gtk_widget_reparent(GTK_WIDGET_PTR(messageview), container);
657                 menu_set_sensitive(ifactory, "/View/Expand Summary View", FALSE);
658                 gtk_widget_grab_focus(GTK_WIDGET(messageview->textview->text));
659         } else {
660                 gtk_widget_reparent(GTK_WIDGET_PTR(messageview), vpaned);
661                 gtk_container_add(GTK_CONTAINER(container), vpaned);
662                 gtk_widget_unref(vpaned);
663                 menu_set_sensitive(ifactory, "/View/Expand Summary View", TRUE);
664                 gtk_widget_grab_focus(GTK_WIDGET(mainwin->summaryview->ctree));
665         }
666 }
667
668 static void return_receipt_show(NoticeView *noticeview, MsgInfo *msginfo)
669 {
670         noticeview_set_text(noticeview, _("This messages asks for a return receipt."));
671         noticeview_set_button_text(noticeview, _("Send receipt"));
672         noticeview_set_button_press_callback(noticeview,
673                                              GTK_SIGNAL_FUNC(return_receipt_send_clicked),
674                                              (gpointer) msginfo);
675         noticeview_show(noticeview);
676 }
677
678 static void return_receipt_send_clicked(NoticeView *noticeview, MsgInfo *msginfo)
679 {
680         MsgInfo *tmpmsginfo;
681         gchar *file;
682
683         file = procmsg_get_message_file_path(msginfo);
684         if (!file) {
685                 g_warning(_("can't get message file path.\n"));
686                 return;
687         }
688
689         tmpmsginfo = procheader_parse_file(file, msginfo->flags, TRUE, TRUE);
690         tmpmsginfo->folder = msginfo->folder;
691         tmpmsginfo->msgnum = msginfo->msgnum;
692
693         if (disposition_notification_send(tmpmsginfo) >= 0) {
694                 procmsg_msginfo_unset_flags(msginfo, MSG_RETRCPT_PENDING, 0);
695                 noticeview_hide(noticeview);
696         }               
697
698         procmsg_msginfo_free(tmpmsginfo);
699         g_free(file);
700 }
701
702 static void select_account_cb(GtkWidget *w, gpointer data)
703 {
704         *(gint*)data = GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(w)));
705 }
706         
707 static PrefsAccount *select_account_from_list(GList *ac_list)
708 {
709         GtkWidget *optmenu;
710         GtkWidget *menu;
711         gint account_id;
712
713         g_return_val_if_fail(ac_list != NULL, NULL);
714         g_return_val_if_fail(ac_list->data != NULL, NULL);
715         
716         optmenu = gtk_option_menu_new();
717         menu = gtkut_account_menu_new(ac_list, select_account_cb, &account_id);
718         if (!menu)
719                 return NULL;
720         gtk_option_menu_set_menu(GTK_OPTION_MENU(optmenu), menu);
721         gtk_option_menu_set_history(GTK_OPTION_MENU(optmenu), 0);
722         account_id = ((PrefsAccount *) ac_list->data)->account_id;
723         if (alertpanel_with_widget(
724                                 _("Return Receipt Notification"),
725                                 _("The message was sent to several of your "
726                                   "accounts.\n"
727                                   "Please choose which account do you want to "
728                                   "use for sending the receipt notification:"),
729                                 _("Send Notification"), _("+Cancel"), NULL,
730                                 optmenu) != G_ALERTDEFAULT)
731                 return NULL;
732         return account_find_from_id(account_id);
733 }