2008-06-04 [colin] 3.4.0cvs82
[claws.git] / src / messageview.c
index 04a011adb4d97814621134873d9fa174b517ebe8..c9cf88c1a56a5edfb9c8c1cfd0491a8b2a0754e8 100644 (file)
@@ -69,6 +69,9 @@
 #include "log.h"
 #include "combobox.h"
 #include "printing.h"
+#include "quoted-printable.h"
+#include "version.h"
+#include "statusbar.h"
 
 static GList *messageview_list = NULL;
 
@@ -77,10 +80,11 @@ static gint messageview_delete_cb   (GtkWidget              *widget,
                                         MessageView            *messageview);
 static void messageview_size_allocate_cb(GtkWidget     *widget,
                                         GtkAllocation  *allocation);
+#ifndef MAEMO
 static gboolean key_pressed            (GtkWidget      *widget,
                                         GdkEventKey    *event,
                                         MessageView    *messageview);
-
+#endif
 static void return_receipt_show                (NoticeView     *noticeview, 
                                         MsgInfo        *msginfo);      
 static void return_receipt_send_clicked (NoticeView    *noticeview, 
@@ -462,6 +466,8 @@ MessageView *messageview_create(MainWindow *mainwin)
        messageview->statusbar     = NULL;
        messageview->statusbar_cid = 0;
 
+       messageview->show_full_text= FALSE;
+
        messageview->msginfo_update_callback_id =
                hooks_register_hook(MSGINFO_UPDATE_HOOKLIST, messageview_update_msg, (gpointer) messageview);
 
@@ -484,12 +490,14 @@ void messageview_update_actions_menu(MessageView *msgview)
        action_update_msgview_menu(ifactory, "/Tools/Actions", msgview);
 }
 
-void messageview_add_toolbar(MessageView *msgview, GtkWidget *window) 
+static void messageview_add_toolbar(MessageView *msgview, GtkWidget *window) 
 {
        GtkWidget *handlebox;
        GtkWidget *vbox;
        GtkWidget *menubar;
+#ifndef GENERIC_UMPC
        GtkWidget *statusbar = NULL;
+#endif
        guint n_menu_entries;
 
        vbox = gtk_vbox_new(FALSE, 0);
@@ -517,12 +525,17 @@ void messageview_add_toolbar(MessageView *msgview, GtkWidget *window)
 #else
        msgview->toolbar = toolbar_create(TOOLBAR_MSGVIEW, handlebox,
                                          (gpointer)msgview);
+#ifndef GENERIC_UMPC
        statusbar = gtk_statusbar_new();
        gtk_widget_show(statusbar);
        gtk_box_pack_end(GTK_BOX(vbox), statusbar, FALSE, FALSE, 0);
        msgview->statusbar = statusbar;
        msgview->statusbar_cid = gtk_statusbar_get_context_id
                (GTK_STATUSBAR(statusbar), "Message View");
+#else
+       msgview->statusbar = NULL;
+       msgview->statusbar_cid = 0;
+#endif
 #endif
 
 
@@ -642,7 +655,11 @@ static gint disposition_notification_send(MsgInfo *msginfo)
         gchar *addrp;
        gchar *foo = NULL;
        gboolean queued_removed = FALSE;
-       
+       gchar *boundary = NULL;
+       gchar *date = NULL;
+       gchar *orig_to = NULL;
+       gchar *enc_sub = NULL;
+
        if (!msginfo->extradata)
                return -1;
        if (!msginfo->extradata->returnreceiptto && 
@@ -758,7 +775,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                    addrp) < 0) {
                g_free(addrp);
                fclose(fp);
-               g_unlink(tmp);
+               claws_unlink(tmp);
                return -1;
        }
 
@@ -773,7 +790,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                if (fprintf(fp, "SCF:%s\n", path) < 0) {
                        g_free(path);
                        fclose(fp);
-                       g_unlink(tmp);
+                       claws_unlink(tmp);
                        return -1;
                }
                g_free(path);
@@ -781,7 +798,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
 
        if (fprintf(fp, "X-Claws-End-Special-Headers: 1\n") < 0) {
                fclose(fp);
-               g_unlink(tmp);
+               claws_unlink(tmp);
                return -1;
        }
 
@@ -789,7 +806,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
        get_rfc822_date(buf, sizeof(buf));
        if (fprintf(fp, "Date: %s\n", buf) < 0) {
                fclose(fp);
-               g_unlink(tmp);
+               claws_unlink(tmp);
                return -1;
        }
 
@@ -800,20 +817,20 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                         strlen("From: "));
                if (fprintf(fp, "From: %s <%s>\n", buf, account->address) < 0) {
                        fclose(fp);
-                       g_unlink(tmp);
+                       claws_unlink(tmp);
                        return -1;
                }
        } else
                if (fprintf(fp, "From: %s\n", account->address) < 0) {
                        fclose(fp);
-                       g_unlink(tmp);
+                       claws_unlink(tmp);
                        return -1;
                }
 
 
        if (fprintf(fp, "To: %s\n", to) < 0) {
                fclose(fp);
-               g_unlink(tmp);
+               claws_unlink(tmp);
                return -1;
        }
 
@@ -822,7 +839,7 @@ static gint disposition_notification_send(MsgInfo *msginfo)
                                    strlen("Subject: "));
        if (fprintf(fp, "Subject: Disposition notification: %s\n", buf) < 0) {
                fclose(fp);
-               g_unlink(tmp);
+               claws_unlink(tmp);
                return -1;
        }
 
@@ -837,17 +854,93 @@ static gint disposition_notification_send(MsgInfo *msginfo)
        } else {
                g_snprintf(buf, sizeof(buf), "%s", "");
        }
-       generate_msgid(buf, sizeof(buf));
-       if (fprintf(fp, "Message-ID: <%s>\n", buf) < 0) {
+       
+       if (account->gen_msgid) {
+               generate_msgid(buf, sizeof(buf));
+
+               if (fprintf(fp, "Message-ID: <%s>\n", buf) < 0) {
+                       fclose(fp);
+                       claws_unlink(tmp);
+                       return -1;
+               }
+       }
+
+       boundary = generate_mime_boundary("DN");
+       get_rfc822_date(buf, sizeof(buf));
+       date = g_strdup(buf);
+       if (msginfo->to) {
+               orig_to = g_strdup(msginfo->to);
+               extract_address(orig_to);
+       }
+       if (msginfo->subject && *(msginfo->subject)) {
+               enc_sub = g_malloc0(strlen(msginfo->subject)*8);
+               qp_encode_line(enc_sub, (const guchar *)msginfo->subject);
+               g_strstrip(enc_sub);
+       }
+       if (fprintf(fp, "MIME-Version: 1.0\n"
+                       "Content-Type: multipart/report; report-type=disposition-notification;\n"
+                       "  boundary=\"%s\"\n"
+                       "\n"
+                       "--%s\n"
+                       "Content-Type: text/plain; charset=UTF-8\n"
+                       "Content-Transfer-Encoding: quoted-printable\n"
+                       "\n"
+                       "The message sent on: %s\n"
+                       "To: %s\n"
+                       "With subject: \"%s\"\n"
+                       "has been displayed at %s.\n"
+                       "\n"
+                       "There is no guarantee that the message has been read or understood.\n"
+                       "\n"
+                       "--%s\n"
+                       "Content-Type: message/disposition-notification\n"
+                       "\n"
+                       "Reporting-UA: %s\n"
+                       "Original-Recipient: rfc822;%s\n"
+                       "Final-Recipient: rfc822;%s\n"
+                       "Original-Message-ID: <%s>\n"
+                       "Disposition: manual-action/MDN-sent-manually; displayed\n"
+                       "\n"
+                       "--%s\n"
+                       "Content-Type: application/octet-stream\n"
+                       "Reporting-UA: %s\n"
+                       "Original-Recipient: rfc822;%s\n"
+                       "Final-Recipient: rfc822;%s\n"
+                       "Original-Message-ID: <%s>\n"
+                       "Disposition: manual-action/MDN-sent-manually; displayed\n"
+                       "\n"
+                       "--%s--\n", 
+                       boundary, 
+                       boundary,
+                       msginfo->date, 
+                       orig_to?orig_to:"No To:",
+                       enc_sub?enc_sub:"No subject",
+                       date,
+                       boundary,
+                       PROG_VERSION,
+                       orig_to?orig_to:"No To:",
+                       account->address,
+                       msginfo->msgid?msginfo->msgid:"NO MESSAGE ID",
+                       boundary,
+                       PROG_VERSION,
+                       orig_to?orig_to:"No To:",
+                       account->address,
+                       msginfo->msgid?msginfo->msgid:"NO MESSAGE ID",
+                       boundary) < 0) {
                fclose(fp);
-               g_unlink(tmp);
+               claws_unlink(tmp);
+               g_free(boundary);
                return -1;
        }
 
+       g_free(enc_sub);
+       g_free(orig_to);
+       g_free(date);
+       g_free(boundary);
 
        if (fclose(fp) == EOF) {
                FILE_OP_ERROR(tmp, "fclose");
-               g_unlink(tmp);
+               claws_unlink(tmp);
                return -1;
        }
 
@@ -856,13 +949,13 @@ static gint disposition_notification_send(MsgInfo *msginfo)
        if (!queue) queue = folder_get_default_queue();
        if (!queue) {
                g_warning("can't find queue folder\n");
-               g_unlink(tmp);
+               claws_unlink(tmp);
                return -1;
        }
        folder_item_scan(queue);
        if ((num = folder_item_add_msg(queue, tmp, NULL, TRUE)) < 0) {
                g_warning("can't queue the message\n");
-               g_unlink(tmp);
+               claws_unlink(tmp);
                return -1;
        }
                
@@ -914,6 +1007,9 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
        gchar *subject = NULL;
        g_return_val_if_fail(msginfo != NULL, -1);
 
+       if (msginfo != messageview->msginfo)
+               messageview->show_full_text = FALSE;
+
        if (messageview->mimeview->textview &&
            messageview->mimeview->textview->loading) {
                messageview->mimeview->textview->stop_loading = TRUE;
@@ -935,9 +1031,20 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
                                messageview->toolbar->learn_spam_btn, 
                                procmsg_spam_can_learn());
        }
+       
+       noticeview_hide(messageview->noticeview);
+       mimeview_clear(messageview->mimeview);
        messageview->updating = TRUE;
 
+       if (msginfo->size > 1024*1024)
+               statuswindow_print_all(_("Fetching message (%s)..."),
+                       to_human_readable(msginfo->size));
+       
        file = procmsg_get_message_file_path(msginfo);
+
+       if (msginfo->size > 1024*1024)
+               statuswindow_pop_all();
+
        if (!file) {
                g_warning("can't get message file path.\n");
                textview_show_error(messageview->mimeview->textview);
@@ -1002,7 +1109,7 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
        }
        mimeview_show_message(messageview->mimeview, mimeinfo, file);
        
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
        messageview_set_position(messageview, 0);
 #endif
 
@@ -1027,18 +1134,18 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
        main_create_mailing_list_menu(messageview->mainwin, messageview->msginfo);
 
        if (messageview->msginfo && messageview->msginfo->extradata
-           && messageview->msginfo->extradata->partial_recv)
+           && messageview->msginfo->extradata->partial_recv
+           && !noticeview_is_visible(messageview->noticeview))
                partial_recv_show(messageview->noticeview, 
                                  messageview->msginfo);
        else if (messageview->msginfo && messageview->msginfo->extradata &&
            (messageview->msginfo->extradata->dispositionnotificationto || 
             messageview->msginfo->extradata->returnreceiptto) &&
            !MSG_IS_RETRCPT_SENT(messageview->msginfo->flags) &&
-           !prefs_common.never_send_retrcpt)
+           !prefs_common.never_send_retrcpt &&
+           !noticeview_is_visible(messageview->noticeview))
                return_receipt_show(messageview->noticeview, 
                                    messageview->msginfo);
-       else 
-               noticeview_hide(messageview->noticeview);
 
        mimeinfo = procmime_mimeinfo_next(mimeinfo);
        if (!all_headers && mimeinfo 
@@ -1046,12 +1153,76 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
            strcasecmp(mimeinfo->subtype, "plain")) 
                        && (mimeinfo->type != MIMETYPE_MULTIPART || 
            strcasecmp(mimeinfo->subtype, "signed"))) {
-               if (strcasecmp(mimeinfo->subtype, "html"))
+               if (strcasecmp(mimeinfo->subtype, "html")) {
+                       MimeInfo *saved_mimeinfo = mimeinfo;
+                       MimeInfo *alt_parent = mimeinfo;
+
+                       /* if multipart/{related,mixed} part, look inside for a multipart/alternative child */
+                       if (prefs_common.promote_html_part &&
+                           mimeinfo->type == MIMETYPE_MULTIPART &&
+                           (!strcasecmp(mimeinfo->subtype, "related") ||
+                            !strcasecmp(mimeinfo->subtype, "mixed"))) {
+                               for (; mimeinfo; mimeinfo = procmime_mimeinfo_next(mimeinfo)) {
+                                       if (mimeinfo->node->parent != saved_mimeinfo->node) {
+                                               /* only consider children of the 
+                                                * multipart/{related,mixed} part */
+                                               continue;
+                                       }
+                                       if (mimeinfo->type == MIMETYPE_MULTIPART && 
+                                           !strcasecmp(mimeinfo->subtype, "alternative")) {
+                                               /* we got an alternative part */
+                                               alt_parent = mimeinfo;
+                                               break;
+                                       }
+                               }
+                       }
+
+                       /* if we now have a multipart/alternative part (possibly inside a
+                        * multipart/{related,mixed} part, look for an HTML part inside */
+                       if (prefs_common.promote_html_part && mimeinfo && 
+                           mimeinfo->type == MIMETYPE_MULTIPART &&
+                           !strcasecmp(mimeinfo->subtype, "alternative")) {
+                               for (; mimeinfo; mimeinfo = procmime_mimeinfo_next(mimeinfo)) {
+                                       if (mimeinfo->node->parent != alt_parent->node) {
+                                               /* only consider children of the 
+                                                * multipart/alternative part, so as
+                                                * not to show html attachments */
+                                               continue;
+                                       }
+                                       if (mimeinfo->type == MIMETYPE_TEXT && 
+                                           !strcasecmp(mimeinfo->subtype, "html")) {
+                                               /* we got it */
+                                               mimeview_select_mimepart_icon(messageview->mimeview, mimeinfo);
+                                               goto done;
+                                       }
+                               }
+                       }
+                       
+                       /* if we didn't find anything, go back to start */
+                       if (!mimeinfo) 
+                               mimeinfo = saved_mimeinfo;
+
                        mimeview_show_part(messageview->mimeview,mimeinfo);
-               else if (prefs_common.invoke_plugin_on_html)
-                       mimeview_select_mimepart_icon(messageview->mimeview,mimeinfo);
+                       goto done;
+               } else if (prefs_common.invoke_plugin_on_html) {
+                       mimeview_select_mimepart_icon(messageview->mimeview, mimeinfo);
+                       goto done;
+               }
        }
-
+       if (!all_headers && mimeinfo &&
+           mimeinfo->type == MIMETYPE_MULTIPART &&
+           mimeview_has_viewer_for_content_type(messageview->mimeview, "text/calendar")) {
+               /* look for a calendar part or it looks really strange */
+               while (mimeinfo) {
+                       if (mimeinfo->type == MIMETYPE_TEXT &&
+                           !strcasecmp(mimeinfo->subtype, "calendar")) {
+                               mimeview_select_mimepart_icon(messageview->mimeview, mimeinfo);
+                               goto done;
+                       }
+                       mimeinfo = procmime_mimeinfo_next(mimeinfo);
+               }
+       }
+done:
        g_free(file);
 
        return 0;
@@ -1176,8 +1347,8 @@ void messageview_delete(MessageView *msgview)
                        /* NOTE: does not update to next message in summaryview */
                }
        }
-#ifdef MAEMO
-       if (msgview->window) {
+#ifdef GENERIC_UMPC
+       if (msgview->window && !prefs_common.always_show_msg) {
                messageview_destroy(msgview);
        }
 #endif
@@ -1204,14 +1375,6 @@ static void messageview_update(MessageView *msgview, MsgInfo *old_msginfo)
        } 
 }
 
-void messageview_quote_color_set(void)
-{
-}
-
-void messageview_set_font(MessageView *messageview)
-{
-}
-
 TextView *messageview_get_current_textview(MessageView *messageview)
 {
        TextView *text = NULL;
@@ -1368,7 +1531,7 @@ static void messageview_size_allocate_cb(GtkWidget *widget,
        prefs_common.msgwin_width  = allocation->width;
        prefs_common.msgwin_height = allocation->height;
 }
-
+#ifndef MAEMO
 static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event,
                        MessageView *messageview)
 {
@@ -1385,6 +1548,30 @@ static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event,
        mimeview_pass_key_press_event(messageview->mimeview, event);
        return FALSE;
 }
+#endif
+
+static void messageview_show_partial_display_cb(NoticeView *noticeview, MessageView *messageview)
+{
+       messageview->show_full_text = TRUE;
+       main_window_cursor_wait(mainwindow_get_mainwindow());
+       GTK_EVENTS_FLUSH();
+       messageview_show(messageview, messageview->msginfo, messageview->all_headers);
+       main_window_cursor_normal(mainwindow_get_mainwindow());
+}
+
+void messageview_show_partial_display(MessageView *messageview, MsgInfo *msginfo,
+                                            size_t length)
+{
+       gchar *msg = g_strdup_printf(_("Show all %s."), to_human_readable((goffset)length));
+       noticeview_set_icon(messageview->noticeview, STOCK_PIXMAP_NOTICE_WARN);
+       noticeview_set_text(messageview->noticeview, _("Only the first megabyte of text is shown."));
+       noticeview_set_button_text(messageview->noticeview, msg);
+       g_free(msg);
+       noticeview_set_button_press_callback(messageview->noticeview,
+                                            G_CALLBACK(messageview_show_partial_display_cb),
+                                            (gpointer) messageview);
+       noticeview_show(messageview->noticeview);
+}
 
 static void return_receipt_show(NoticeView *noticeview, MsgInfo *msginfo)
 {
@@ -1398,7 +1585,7 @@ static void return_receipt_show(NoticeView *noticeview, MsgInfo *msginfo)
        addr = g_strdup(msginfo->from);
        if (addr) {
                extract_address(addr);
-               if (account_find_from_address(addr)) {
+               if (account_find_from_address(addr, FALSE)) {
                        from_me = TRUE;
                }
                g_free(addr);
@@ -1406,7 +1593,12 @@ static void return_receipt_show(NoticeView *noticeview, MsgInfo *msginfo)
 
        if (from_me) {
                noticeview_set_icon(noticeview, STOCK_PIXMAP_NOTICE_WARN);
-               noticeview_set_text(noticeview, _("You asked for a return receipt in this message."));
+               if (MSG_IS_RETRCPT_GOT(msginfo->flags)) {
+                       noticeview_set_text(noticeview, _("You got a return receipt in this message : "
+                                                         "it has been displayed by the recipient."));
+               } else {
+                       noticeview_set_text(noticeview, _("You asked for a return receipt in this message."));
+               }
                noticeview_set_button_text(noticeview, NULL);
                noticeview_set_button_press_callback(noticeview, NULL, NULL);
        } else {
@@ -1464,7 +1656,7 @@ static void partial_recv_show(NoticeView *noticeview, MsgInfo *msginfo)
                        text = g_strdup_printf(_("This message has been "
                                        "partially retrieved;\nit is %s."),
                                        to_human_readable(
-                                               (off_t)(msginfo->total_size)));
+                                               (goffset)(msginfo->total_size)));
                        button1 = _("Mark for download");
                        button2 = _("Mark for deletion");
                        button1_cb = partial_recv_dload_clicked;
@@ -1475,7 +1667,7 @@ static void partial_recv_show(NoticeView *noticeview, MsgInfo *msginfo)
                                        "partially retrieved;\nit is %s and "
                                        "will be downloaded."),
                                        to_human_readable(
-                                               (off_t)(msginfo->total_size)));
+                                               (goffset)(msginfo->total_size)));
                        button1 = _("Unmark");
                        button1_cb = partial_recv_unmark_clicked;
                        button2 = _("Mark for deletion");
@@ -1486,7 +1678,7 @@ static void partial_recv_show(NoticeView *noticeview, MsgInfo *msginfo)
                                        "partially retrieved;\nit is %s and "
                                        "will be deleted."),
                                        to_human_readable(
-                                               (off_t)(msginfo->total_size)));
+                                               (goffset)(msginfo->total_size)));
                        button1 = _("Mark for download");
                        button1_cb = partial_recv_dload_clicked;
                        button2 = _("Unmark");
@@ -1777,7 +1969,7 @@ static void prev_cb(gpointer data, guint action, GtkWidget *widget)
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -1802,7 +1994,7 @@ static void next_cb(gpointer data, guint action, GtkWidget *widget)
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -1827,7 +2019,7 @@ static void prev_unread_cb(gpointer data, guint action, GtkWidget *widget)
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -1852,7 +2044,7 @@ static void next_unread_cb(gpointer data, guint action, GtkWidget *widget)
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -1877,7 +2069,7 @@ static void prev_new_cb(gpointer data, guint action, GtkWidget *widget)
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -1902,7 +2094,7 @@ static void next_new_cb(gpointer data, guint action, GtkWidget *widget)
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -1927,7 +2119,7 @@ static void prev_marked_cb(gpointer data, guint action, GtkWidget *widget)
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -1952,7 +2144,7 @@ static void next_marked_cb(gpointer data, guint action, GtkWidget *widget)
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -1977,7 +2169,7 @@ static void prev_labeled_cb(gpointer data, guint action, GtkWidget *widget)
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -2002,7 +2194,7 @@ static void next_labeled_cb(gpointer data, guint action, GtkWidget *widget)
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -2027,7 +2219,7 @@ static void last_read_cb(gpointer data, guint action, GtkWidget *widget)
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -2052,7 +2244,7 @@ static void parent_cb(gpointer data, guint action, GtkWidget *widget)
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -2077,7 +2269,7 @@ static void goto_unread_folder_cb(gpointer data, guint action, GtkWidget *widget
                return;
        }
        if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                if (msginfo)
@@ -2096,7 +2288,7 @@ static void goto_folder_cb(gpointer data, guint action, GtkWidget *widget)
        FolderItem *to_folder;
        messageview->updating = FALSE;
 
-       to_folder = foldersel_folder_sel(NULL, FOLDER_SEL_ALL, NULL);
+       to_folder = foldersel_folder_sel(NULL, FOLDER_SEL_ALL, NULL, FALSE);
 
        if (to_folder) {
                folderview_select(messageview->mainwin->folderview, to_folder);
@@ -2107,7 +2299,7 @@ static void goto_folder_cb(gpointer data, guint action, GtkWidget *widget)
                        return;
                }
                if (messageview->mainwin->summaryview->selected) {
-#ifndef MAEMO
+#ifndef GENERIC_UMPC
                        MsgInfo * msginfo = summary_get_selected_msg(messageview->mainwin->summaryview);
                       
                        if (msginfo)
@@ -2408,6 +2600,7 @@ void messageview_list_urls (MessageView   *msgview)
 {
        GSList *cur = msgview->mimeview->textview->uri_list;
        GSList *newlist = NULL;
+       GHashTable *uri_hashtable = g_hash_table_new(g_str_hash, g_str_equal); 
        for (; cur; cur = cur->next) {
                ClickableText *uri = (ClickableText *)cur->data;
                if (uri->uri &&
@@ -2416,9 +2609,17 @@ void messageview_list_urls (MessageView  *msgview)
                     !g_ascii_strncasecmp(uri->uri, "www.", 4) ||
                     !g_ascii_strncasecmp(uri->uri, "http:", 5) ||
                     !g_ascii_strncasecmp(uri->uri, "https:", 6)))
+               {
+                       if(g_hash_table_lookup(uri_hashtable, uri->uri))
+                               continue;
+                       
                        newlist = g_slist_prepend(newlist, uri);
+                       g_hash_table_insert(uri_hashtable, uri->uri,
+                                           GUINT_TO_POINTER(g_str_hash(uri->uri)));
+               }
        }
        newlist = g_slist_reverse(newlist);
        uri_opener_open(msgview, newlist);
        g_slist_free(newlist);
+       g_hash_table_destroy(uri_hashtable);
 }