Changeset 984

Show
Ignore:
Timestamp:
10/12/06 23:34:55
Author:
pvanhoof
Message:

The new TnyMimePartView API

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ChangeLog

    r978 r984  
     12006-10-12  Philip Van Hoof <pvanhoof@gnome.org> 
     2 
     3        * The new TnyMimePartView API 
     4        * The TnyMimePartView API implemented for Gtk+ 
     5        * The TnyMimePartView API implemented for GtkMozEmbed 
     6 
    172006-09-26  Philip Van Hoof <pvanhoof@gnome.org> 
    28 
  • trunk/libtinymail-camel/tny-camel-mime-part.c

    r900 r984  
    501501        TnyCamelMimePart *self = (TnyCamelMimePart*) object; 
    502502        TnyCamelMimePartPriv *priv = TNY_CAMEL_MIME_PART_GET_PRIVATE (self); 
    503  
     503         
    504504        g_mutex_lock (priv->part_lock); 
    505505        if (priv->cached_content_type) 
  • trunk/libtinymailui-gtk/Makefile.am

    r947 r984  
    1414        tny-gtk-msg-view.h              \ 
    1515        tny-gtk-msg-window.h            \ 
     16        tny-gtk-text-mime-part-view.h   \ 
    1617        tny-gtk-header-list-model.h     \ 
    1718        tny-gtk-folder-tree-model.h     \ 
     
    2627        tny-gtk-save-strategy.c                 \ 
    2728        tny-gtk-msg-view.c                      \ 
     29        tny-gtk-text-mime-part-view.c           \ 
    2830        tny-gtk-msg-window.c                    \ 
    2931        tny-gtk-folder-tree-model.c             \ 
  • trunk/libtinymailui-gtk/tny-gtk-msg-view.c

    r908 r984  
    3333 
    3434#include <tny-list.h> 
     35#include <tny-simple-list.h> 
    3536#include <tny-iterator.h> 
    3637 
     
    4041#include <tny-header-view.h> 
    4142#include <tny-gtk-header-view.h> 
     43#include <tny-gtk-text-mime-part-view.h> 
    4244 
    4345#ifdef GNOME 
     
    5860{ 
    5961        TnyMsg *msg; 
    60         GtkTextView *textview; 
    6162        TnyHeaderView *headerview; 
    62         GtkIconView *attachview; 
    63         GtkWidget *attachview_sw; 
    6463        TnySaveStrategy *save_strategy; 
    6564}; 
     
    6867        (G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_GTK_MSG_VIEW, TnyGtkMsgViewPriv)) 
    6968 
     69 
     70static TnyMimePartView* 
     71tny_gtk_msg_view_create_mime_part_view_for (TnyMsgView *self, TnyMimePart *part) 
     72{ 
     73        return TNY_GTK_MSG_VIEW_GET_CLASS (self)->create_mime_part_view_for_func (self, part); 
     74} 
     75 
     76static TnyMimePartView* 
     77tny_gtk_msg_view_create_mime_part_view_for_defimpl (TnyMsgView *self, TnyMimePart *part) 
     78{ 
     79        TnyGtkMsgViewPriv *priv = TNY_GTK_MSG_VIEW_GET_PRIVATE (self); 
     80        TnyMimePartView *retval = NULL; 
     81 
     82        if (tny_mime_part_content_type_is (part, "text/*")) 
     83        { 
     84                retval = tny_gtk_text_mime_part_view_new (priv->save_strategy); 
     85                gtk_box_pack_start (GTK_BOX (TNY_GTK_MSG_VIEW (self)->viewers), GTK_WIDGET (retval), TRUE, TRUE, 0); 
     86                gtk_widget_show (GTK_WIDGET (retval)); 
     87        } 
     88         
     89        return retval; 
     90} 
     91 
    7092static void 
    7193reload_msg (TnyMsgView *self) 
    7294{ 
    7395        TnyGtkMsgViewPriv *priv = TNY_GTK_MSG_VIEW_GET_PRIVATE (self); 
    74         GtkTextBuffer *buffer; 
    7596        TnyHeader *header; 
    7697        TnyIterator *iterator; 
    77         gboolean first_attach = TRUE; 
    78         GtkTreeModel *model; 
    79  
     98        TnyList *list = tny_simple_list_new (); 
     99         
    80100        g_return_if_fail (TNY_IS_MSG (priv->msg)); 
    81101 
     
    84104        tny_header_view_set_header (priv->headerview, header); 
    85105        g_object_unref (G_OBJECT (header)); 
    86  
    87         buffer = gtk_text_view_get_buffer (priv->textview); 
    88106     
    89         model = tny_gtk_attach_list_model_new (); 
    90         tny_msg_get_parts (priv->msg, TNY_LIST (model)); 
    91         iterator = tny_list_create_iterator (TNY_LIST (model)); 
    92  
    93         gtk_widget_hide (priv->attachview_sw); 
    94         gtk_text_buffer_set_text (buffer, "", 0); 
    95      
     107        tny_msg_get_parts (priv->msg, list); 
     108        iterator = tny_list_create_iterator (list); 
     109 
    96110        gtk_widget_show (GTK_WIDGET (priv->headerview)); 
    97111 
     
    99113        { 
    100114                TnyMimePart *part = (TnyMimePart*)tny_iterator_get_current (iterator); 
    101  
    102                 if (G_LIKELY (tny_mime_part_content_type_is (part, "text/*"))) 
    103                 { 
    104                         TnyStream *dest = tny_gtk_text_buffer_stream_new (buffer); 
    105                      
    106                         tny_stream_reset (dest); 
    107                         tny_mime_part_write_to_stream (part, dest); 
    108                         tny_stream_reset (dest); 
    109  
    110                         g_object_unref (G_OBJECT (dest)); 
    111                      
    112                 } else if (tny_mime_part_get_content_type (part) && 
    113                         tny_mime_part_is_attachment (part)) 
    114                 {                        
    115                         first_attach = FALSE; 
    116                 } 
     115                TnyMimePartView *mpview; 
     116 
     117                mpview = tny_msg_view_create_mime_part_view_for (self, part); 
     118                 
     119                if (mpview) 
     120                        tny_mime_part_view_set_part (mpview, part); 
    117121                 
    118122                g_object_unref (G_OBJECT(part)); 
     
    121125 
    122126        g_object_unref (G_OBJECT (iterator)); 
    123  
    124  
    125         if (G_LIKELY (!first_attach)) 
    126         { 
    127                 gtk_icon_view_set_model (priv->attachview, model); 
    128                 gtk_widget_show (priv->attachview_sw); 
    129         } 
    130  
    131         g_object_unref (G_OBJECT (model)); 
    132  
    133         return; 
    134 
    135  
    136 void 
     127        g_object_unref (G_OBJECT (list)); 
     128         
     129        return; 
     130
     131 
     132 
     133static void 
    137134tny_gtk_msg_view_set_save_strategy (TnyMsgView *self, TnySaveStrategy *strategy) 
     135{ 
     136        TNY_GTK_MSG_VIEW_GET_CLASS (self)->set_save_strategy_func (self, strategy); 
     137} 
     138 
     139static void 
     140tny_gtk_msg_view_set_save_strategy_defimpl (TnyMsgView *self, TnySaveStrategy *strategy) 
    138141{ 
    139142        TnyGtkMsgViewPriv *priv = TNY_GTK_MSG_VIEW_GET_PRIVATE (self); 
     
    150153 
    151154static void 
    152 for_each_selected_attachment (GtkIconView *icon_view, GtkTreePath *path, gpointer user_data) 
     155tny_gtk_msg_view_save_as_activated (GtkMenuItem *menuitem, gpointer user_data) 
    153156{ 
    154157        TnyGtkMsgView *self = user_data; 
    155158        TnyGtkMsgViewPriv *priv = TNY_GTK_MSG_VIEW_GET_PRIVATE (self); 
    156         GtkTreeModel *model = gtk_icon_view_get_model (icon_view); 
    157         GtkTreeIter iter; 
    158159 
    159160        if (!G_LIKELY (priv->save_strategy)) 
     
    162163                return; 
    163164        } 
    164  
    165         if (G_LIKELY (gtk_tree_model_get_iter(model, &iter, path))) 
    166         { 
    167                 TnyMimePart *part; 
    168  
    169                 gtk_tree_model_get (model, &iter,  
    170                         TNY_GTK_ATTACH_LIST_MODEL_INSTANCE_COLUMN,  
    171                         &part, -1); 
    172  
    173                 if (G_LIKELY (part)) 
    174                 { 
    175                         tny_save_strategy_save (priv->save_strategy, part); 
    176                         g_object_unref (G_OBJECT (part)); 
    177                 } 
    178         } 
    179  
    180         return; 
    181 
    182  
    183  
    184 static void 
    185 tny_gtk_msg_view_save_as_activated (GtkMenuItem *menuitem, gpointer user_data) 
    186 
    187         TnyGtkMsgView *self = user_data; 
    188         TnyGtkMsgViewPriv *priv = TNY_GTK_MSG_VIEW_GET_PRIVATE (self); 
    189  
    190         if (!G_LIKELY (priv->save_strategy)) 
    191         { 
    192                 g_warning (_("No save strategy for this message view\n")); 
    193                 return; 
    194         } 
    195  
    196         gtk_icon_view_selected_foreach (priv->attachview, 
    197                 for_each_selected_attachment, self); 
    198  
    199         return; 
    200 
    201  
     165         
     166        tny_save_strategy_save (priv->save_strategy, TNY_MIME_PART (self)); 
     167         
     168        return; 
     169
    202170 
    203171 
     
    232200tny_gtk_msg_view_set_unavailable (TnyMsgView *self) 
    233201{ 
     202        TNY_GTK_MSG_VIEW_GET_CLASS (self)->set_unavailable_func (self); 
     203} 
     204 
     205static void 
     206tny_gtk_msg_view_set_unavailable_defimpl (TnyMsgView *self) 
     207{ 
    234208        TnyGtkMsgViewPriv *priv = TNY_GTK_MSG_VIEW_GET_PRIVATE (self); 
    235209        GtkTextBuffer *buffer; 
     
    241215        } 
    242216 
    243         buffer = gtk_text_view_get_buffer (priv->textview); 
    244         gtk_widget_hide (priv->attachview_sw); 
    245         gtk_text_buffer_set_text (buffer, _("Message is unavailable"), -1); 
    246  
    247217        tny_header_view_clear (priv->headerview); 
    248218        gtk_widget_hide (GTK_WIDGET (priv->headerview)); 
     
    251221} 
    252222 
     223static void 
     224tny_gtk_msg_view_set_msg (TnyMsgView *self, TnyMsg *msg) 
     225{ 
     226        TNY_GTK_MSG_VIEW_GET_CLASS (self)->set_msg_func (self, msg); 
     227} 
     228 
    253229static void  
    254 tny_gtk_msg_view_set_msg (TnyMsgView *self, TnyMsg *msg) 
    255 
    256         TnyGtkMsgViewPriv *priv = TNY_GTK_MSG_VIEW_GET_PRIVATE (self); 
    257  
    258         if (G_LIKELY (priv->msg)) 
    259                 g_object_unref (G_OBJECT (priv->msg)); 
    260      
     230tny_gtk_msg_view_set_msg_defimpl (TnyMsgView *self, TnyMsg *msg) 
     231
     232        TnyGtkMsgViewPriv *priv = TNY_GTK_MSG_VIEW_GET_PRIVATE (self); 
     233 
     234        tny_msg_view_clear (self); 
     235 
    261236        if (msg) 
    262237        { 
     
    270245 
    271246static void 
     247remove_mime_part_viewer (TnyMimePartView *mpview, GtkContainer *mpviewers) 
     248{ 
     249        gtk_container_remove (mpviewers, GTK_WIDGET (mpview)); 
     250        return; 
     251} 
     252 
     253static void 
    272254tny_gtk_msg_view_clear (TnyMsgView *self) 
    273255{ 
    274         TnyGtkMsgViewPriv *priv = TNY_GTK_MSG_VIEW_GET_PRIVATE (self); 
    275  
    276         GtkTextBuffer *buffer = gtk_text_view_get_buffer (priv->textview); 
    277         gtk_widget_hide (priv->attachview_sw); 
    278         gtk_text_buffer_set_text (buffer, "", 0); 
     256        TNY_GTK_MSG_VIEW_GET_CLASS (self)->clear_func (self); 
     257
     258 
     259static void 
     260tny_gtk_msg_view_clear_defimpl (TnyMsgView *self) 
     261
     262        TnyGtkMsgViewPriv *priv = TNY_GTK_MSG_VIEW_GET_PRIVATE (self); 
     263        GList *kids = gtk_container_get_children (GTK_CONTAINER (TNY_GTK_MSG_VIEW (self)->viewers)); 
     264        g_list_foreach (kids, (GFunc)remove_mime_part_viewer, TNY_GTK_MSG_VIEW (self)->viewers); 
     265        g_list_free (kids); 
     266         
     267        if (G_LIKELY (priv->msg)) 
     268                g_object_unref (G_OBJECT (priv->msg)); 
     269        priv->msg = NULL; 
     270         
    279271        tny_header_view_set_header (priv->headerview, NULL); 
    280272        gtk_widget_hide (GTK_WIDGET (priv->headerview)); 
     
    307299        GtkMenu *menu = GTK_MENU (gtk_menu_new ()); 
    308300        GtkWidget *mitem = gtk_menu_item_new_with_mnemonic ("Save _As"); 
    309  
     301         
    310302        priv->save_strategy = NULL; 
    311  
     303         
    312304        gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (self), NULL); 
    313305        gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (self), NULL); 
     
    319311 
    320312        gtk_menu_shell_append (GTK_MENU_SHELL (menu), mitem); 
    321  
    322         priv->attachview_sw = gtk_scrolled_window_new (NULL, NULL); 
    323313 
    324314        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (self),  
     
    326316        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self), 
    327317                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 
    328         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->attachview_sw),  
    329                         GTK_SHADOW_NONE); 
    330         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->attachview_sw), 
    331                         GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); 
    332  
    333         priv->attachview = GTK_ICON_VIEW (gtk_icon_view_new ()); 
    334  
    335         gtk_icon_view_set_selection_mode (priv->attachview, GTK_SELECTION_SINGLE); 
    336  
    337         g_signal_connect_swapped (G_OBJECT (priv->attachview), "button_press_event", 
     318                         
     319        g_signal_connect_swapped (G_OBJECT (self), "button_press_event", 
    338320                G_CALLBACK (tny_gtk_msg_view_popup_handler), menu); 
    339321 
    340         gtk_icon_view_set_text_column (priv->attachview,  
    341                 TNY_GTK_ATTACH_LIST_MODEL_FILENAME_COLUMN); 
    342  
    343         gtk_icon_view_set_pixbuf_column (priv->attachview,  
    344                 TNY_GTK_ATTACH_LIST_MODEL_PIXBUF_COLUMN); 
    345  
    346         gtk_icon_view_set_columns (priv->attachview, -1); 
    347         gtk_icon_view_set_item_width (priv->attachview, 100); 
    348         gtk_icon_view_set_column_spacing (priv->attachview, 10); 
    349  
    350322        priv->headerview = tny_gtk_header_view_new (); 
    351  
    352         priv->textview = GTK_TEXT_VIEW (gtk_text_view_new ()); 
    353  
    354         gtk_text_view_set_editable (priv->textview, FALSE); 
    355  
    356323        gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->headerview), FALSE, FALSE, 0); 
    357         gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->textview), TRUE, TRUE, 0);         
    358         gtk_box_pack_start (GTK_BOX (vbox), priv->attachview_sw, FALSE, TRUE, 0); 
    359  
     324         
     325        TNY_GTK_MSG_VIEW (self)->viewers = GTK_BOX (gtk_vbox_new (FALSE, 1)); 
     326        gtk_box_pack_start (GTK_BOX (vbox),  
     327                GTK_WIDGET (TNY_GTK_MSG_VIEW (self)->viewers), FALSE, FALSE, 0); 
     328        gtk_widget_show (GTK_WIDGET (TNY_GTK_MSG_VIEW (self)->viewers)); 
     329         
    360330        gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (self),  
    361331                        GTK_WIDGET (vbox)); 
    362332 
    363         gtk_container_add (GTK_CONTAINER (priv->attachview_sw), GTK_WIDGET (priv->attachview)); 
    364  
    365333        gtk_widget_show (GTK_WIDGET (vbox)); 
    366  
    367334        gtk_widget_hide (GTK_WIDGET (priv->headerview)); 
    368         gtk_widget_show (GTK_WIDGET (priv->textview)); 
    369         gtk_widget_show (GTK_WIDGET (priv->attachview)); 
    370335 
    371336        return; 
     
    383348        if (G_LIKELY (priv->save_strategy)) 
    384349                g_object_unref (G_OBJECT (priv->save_strategy)); 
    385  
    386         /* priv->headerview will be destroyed as a GtkObject */ 
    387      
     350             
    388351        (*parent_class->finalize) (object); 
    389352 
     
    400363        klass->set_unavailable_func = tny_gtk_msg_view_set_unavailable; 
    401364        klass->clear_func = tny_gtk_msg_view_clear; 
    402      
     365        klass->create_mime_part_view_for_func = tny_gtk_msg_view_create_mime_part_view_for; 
     366         
    403367        return; 
    404368} 
     
    414378        object_class->finalize = tny_gtk_msg_view_finalize; 
    415379 
     380        class->set_msg_func = tny_gtk_msg_view_set_msg_defimpl; 
     381        class->set_save_strategy_func = tny_gtk_msg_view_set_save_strategy_defimpl; 
     382        class->set_unavailable_func = tny_gtk_msg_view_set_unavailable_defimpl; 
     383        class->clear_func = tny_gtk_msg_view_clear_defimpl; 
     384        class->create_mime_part_view_for_func = tny_gtk_msg_view_create_mime_part_view_for_defimpl; 
     385         
    416386        g_type_class_add_private (object_class, sizeof (TnyGtkMsgViewPriv)); 
    417387 
  • trunk/libtinymailui-gtk/tny-gtk-msg-view.h

    r900 r984  
    3333G_BEGIN_DECLS 
    3434 
    35 #define TNY_TYPE_GTK_MSG_VIEW         (tny_gtk_msg_view_get_type ()) 
     35#define TNY_TYPE_GTK_MSG_VIEW             (tny_gtk_msg_view_get_type ()) 
    3636#define TNY_GTK_MSG_VIEW(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), TNY_TYPE_GTK_MSG_VIEW, TnyGtkMsgView)) 
    3737#define TNY_GTK_MSG_VIEW_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST ((vtable), TNY_TYPE_GTK_MSG_VIEW, TnyGtkMsgViewClass)) 
     
    4646{ 
    4747        GtkScrolledWindow parent; 
    48  
     48        GtkBox *viewers; 
    4949}; 
    5050 
     
    5252{ 
    5353        GtkScrolledWindowClass parent_class; 
     54         
     55        /* virtual methods (they have a default implementation in TnyGtkMsgView */ 
     56        void (*set_msg_func) (TnyMsgView *self, TnyMsg *msg); 
     57        void (*set_save_strategy_func) (TnyMsgView *self, TnySaveStrategy *strategy); 
     58        void (*set_unavailable_func) (TnyMsgView *self); 
     59        void (*clear_func) (TnyMsgView *self); 
     60        TnyMimePartView* (*create_mime_part_view_for_func) (TnyMsgView *self, TnyMimePart *part);        
    5461}; 
    5562 
  • trunk/libtinymailui-mozembed/Makefile.am

    r379 r984  
    1414libtinymailui_mozembed_1_0_headers =             \ 
    1515        tny-moz-embed-msg-view.h                 \ 
     16        tny-moz-embed-html-mime-part-view.h     \ 
    1617        tny-moz-embed-stream.h 
    1718 
    1819libtinymailui_mozembed_1_0_la_SOURCES =          \ 
    1920        $(libtinymailui_mozembed_1_0_headers)    \ 
     21        tny-moz-embed-html-mime-part-view.c      \ 
    2022        tny-moz-embed-msg-view.c                 \ 
    2123        tny-moz-embed-stream.c 
  • trunk/libtinymailui-mozembed/tny-moz-embed-msg-view.c

    r906 r984  
    2020#include <config.h> 
    2121#include <glib/gi18n-lib.h> 
    22  
    23 #include <unistd.h> 
    24 #include <fcntl.h> 
    25 #include <stdio.h> 
    26 #include <stdlib.h> 
    27 #include <sys/stat.h> 
    28 #include <sys/types.h> 
    29  
    30 #include <string.h> 
    3122#include <gtk/gtk.h> 
    32 #include <tny-list.h> 
    33 #include <tny-iterator.h> 
    3423 
    3524#include <tny-moz-embed-msg-view.h> 
    36 #include <tny-moz-embed-stream.h> 
    37 #include <tny-gtk-attach-list-model.h> 
    38 #include <tny-header-view.h> 
    39 #include <tny-gtk-header-view.h> 
    40 #include <tny-gtk-text-buffer-stream.h> 
    41  
    42 #ifdef GNOME 
    43 #include <tny-vfs-stream.h> 
    44 #include <libgnomevfs/gnome-vfs.h> 
    45 #include <libgnomevfs/gnome-vfs-utils.h> 
    46 #else 
    47 #include <tny-fs-stream.h> 
    48 #endif 
    49  
    50 #include "tny-gtk-attach-list-model-priv.h" 
     25#include <tny-moz-embed-html-mime-part-view.h> 
    5126 
    5227static GObjectClass *parent_class = NULL; 
     
    5631struct _TnyMozEmbedMsgViewPriv 
    5732{ 
    58         TnyMsg *msg; 
    59         GtkTextView *textview; 
    60         TnyHeaderView *headerview; 
    61         GtkMozEmbed *htmlview; 
    62          
    63         GtkIconView *attachview; 
    64         GtkWidget *attachview_sw; 
    6533        TnySaveStrategy *save_strategy; 
    6634}; 
    6735 
    68 #define TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE(o) 
     36#define TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE(o)
    6937        (G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_MOZ_EMBED_MSG_VIEW, TnyMozEmbedMsgViewPriv)) 
    7038 
    71  
    72 static gpointer  
    73 remove_html_stread_hack (gpointer data) 
    74 { 
    75         /* Sigh, I don't know why I need this :-(. I think GtkMozEmbed postpones 
    76            the loading of the document to the very last moment. */ 
    77  
    78         sleep (5); 
    79  
    80         /* This will remove the file in /tmp/ */ 
    81         g_object_unref (G_OBJECT (data)); 
    82  
    83         return NULL; 
    84 } 
    85  
    86 static void 
    87 reload_msg (TnyMsgView *self) 
    88 { 
    89         TnyMozEmbedMsgViewPriv *priv = TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE (self); 
    90         GtkTextBuffer *buffer; 
    91         TnyHeader *header; 
    92         TnyIterator *iterator; 
    93         gboolean first_attach = TRUE; 
    94         GtkTreeModel *model; 
    95         gboolean have_html = FALSE; 
    96  
    97         tny_header_view_clear (TNY_HEADER_VIEW (priv->headerview)); 
    98      
    99         g_return_if_fail (TNY_IS_MSG (priv->msg)); 
    100  
    101         header = TNY_HEADER (tny_msg_get_header (priv->msg));     
    102         g_return_if_fail (TNY_IS_HEADER (header)); 
    103         tny_header_view_set_header (priv->headerview, header); 
    104         g_object_unref (G_OBJECT (header)); 
    105  
    106         buffer = gtk_text_view_get_buffer (priv->textview); 
    107      
    108         model = tny_gtk_attach_list_model_new ();; 
    109         tny_msg_get_parts (priv->msg, TNY_LIST (model)); 
    110         iterator = tny_list_create_iterator (TNY_LIST (model)); 
    111         gtk_widget_hide (priv->attachview_sw); 
    112  
    113         gtk_text_buffer_set_text (buffer, "", 0); 
    114         gtk_widget_show (GTK_WIDGET (priv->headerview)); 
    115  
    116         while (!tny_iterator_is_done (iterator)) 
    117         { 
    118                 TnyMimePart *part = (TnyMimePart*)tny_iterator_get_current (iterator); 
    119  
    120                 if (!have_html && G_LIKELY (tny_mime_part_content_type_is (part, "text/plain"))) 
    121                 { 
    122                         TnyStream *dest = NULL; 
    123  
    124                         gtk_widget_hide (GTK_WIDGET (priv->htmlview)); 
    125                         gtk_widget_show (GTK_WIDGET (priv->textview)); 
    126  
    127                         dest = tny_gtk_text_buffer_stream_new (buffer); 
    128  
    129                         tny_stream_reset (dest); 
    130                         tny_mime_part_decode_to_stream (part, dest); 
    131                         tny_stream_reset (dest); 
    132  
    133                         g_object_unref (G_OBJECT (dest)); 
    134  
    135                 } else if (G_LIKELY (tny_mime_part_content_type_is (part, "text/html"))) 
    136                 { 
    137                         TnyStream *dest = NULL; 
    138  
    139                         dest = TNY_STREAM (tny_moz_embed_stream_new (priv->htmlview)); 
    140  
    141                         have_html = TRUE; 
    142  
    143                         gtk_widget_show (GTK_WIDGET (priv->htmlview)); 
    144                         gtk_widget_hide (GTK_WIDGET (priv->textview)); 
    145  
    146                         tny_stream_reset (dest); 
    147                         tny_mime_part_decode_to_stream (part, dest); 
    148  
    149                         /* This will do: g_object_unref (G_OBJECT (dest)); */ 
    150                         g_thread_create (remove_html_stread_hack, dest, FALSE, NULL); 
    151                          
    152                 } else if (tny_mime_part_get_content_type (part) && 
    153                         tny_mime_part_is_attachment (part)) 
    154                 { 
    155                         first_attach = FALSE; 
    156                 } 
    157                 g_object_unref (G_OBJECT(part)); 
    158                  
    159                 tny_iterator_next (iterator); 
    160         } 
    161  
    162         g_object_unref (G_OBJECT (iterator)); 
    163  
    164         if (G_LIKELY (!first_attach)) 
    165         { 
    166                 gtk_icon_view_set_model (priv->attachview, GTK_TREE_MODEL (model)); 
    167                 gtk_widget_show (priv->attachview_sw); 
    168         } 
    169  
    170         g_object_unref (G_OBJECT (model)); 
    171  
    172         return; 
    173 } 
    174  
    175  
    176 void 
    177 tny_mozembed_msg_view_set_save_strategy (TnyMsgView *self, TnySaveStrategy *strategy) 
    178 { 
    179         TnyMozEmbedMsgViewPriv *priv = TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE (self); 
    180  
    181         if (priv->save_strategy) 
    182                 g_object_unref (G_OBJECT (priv->save_strategy)); 
    183         priv->save_strategy = NULL; 
    184      
    185         g_object_ref (G_OBJECT (strategy)); 
    186         priv->save_strategy = strategy; 
    187  
    188         return; 
    189 } 
    190  
    191 static void 
    192 tny_mozembed_msg_view_set_unavailable (TnyMsgView *self) 
    193 { 
    194         TnyMozEmbedMsgViewPriv *priv = TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE (self); 
    195         GtkTextBuffer *buffer; 
    196  
    197         if (G_LIKELY (priv->msg))  
    198         { 
    199                 g_object_unref (G_OBJECT (priv->msg)); 
    200                 priv->msg = NULL; 
    201         } 
    202      
    203         gtk_widget_hide (GTK_WIDGET (priv->htmlview)); 
    204         gtk_widget_show (GTK_WIDGET (priv->textview)); 
    205  
    206         buffer = gtk_text_view_get_buffer (priv->textview); 
    207         gtk_widget_hide (priv->attachview_sw); 
    208         gtk_text_buffer_set_text (buffer, _("Message is unavailable"), -1); 
    209  
    210         tny_header_view_clear (priv->headerview); 
    211         gtk_widget_hide (GTK_WIDGET (priv->headerview)); 
    212  
    213  
    214         return; 
    215 } 
    216  
    217  
    218 static void 
    219 for_each_selected_attachment (GtkIconView *icon_view, GtkTreePath *path, gpointer user_data) 
    220 { 
    221         TnyMozEmbedMsgView *self = (TnyMozEmbedMsgView*)user_data; 
    222         TnyMozEmbedMsgViewPriv *priv = TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE (self); 
    223         GtkTreeModel *model = gtk_icon_view_get_model (icon_view); 
    224         GtkTreeIter iter; 
    225  
    226         if (!G_LIKELY (priv->save_strategy)) 
    227         { 
    228                 g_warning (_("No save strategy for this message view\n")); 
    229                 return; 
    230         } 
    231  
    232         if (G_LIKELY (gtk_tree_model_get_iter (model, &iter, path))) 
    233         { 
    234                 TnyMimePart *part; 
    235  
    236                 gtk_tree_model_get (model, &iter,  
    237                         TNY_GTK_ATTACH_LIST_MODEL_INSTANCE_COLUMN,  
    238                         &part, -1); 
    239  
    240                 if (G_LIKELY (part)) 
    241                 { 
    242                         tny_save_strategy_save (priv->save_strategy, part);     
    243                         g_object_unref (G_OBJECT (part)); 
    244                 } 
    245         } 
    246  
    247         return; 
    248 } 
    249  
    250  
    251 static void 
    252 tny_moz_embed_msg_view_save_as_activated (GtkMenuItem *menuitem, gpointer user_data) 
    253 { 
    254         TnyMozEmbedMsgView *self = user_data; 
    255         TnyMozEmbedMsgViewPriv *priv = TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE (self); 
    256  
    257         if (!G_LIKELY (priv->save_strategy)) 
    258         { 
    259                 g_warning (_("No save strategy for this message view\n")); 
    260                 return; 
    261         } 
    262  
    263         gtk_icon_view_selected_foreach (priv->attachview, 
    264                 for_each_selected_attachment, self); 
    265  
    266         return; 
    267 } 
    268  
    269  
    270  
    271 static gint 
    272 tny_moz_embed_msg_view_popup_handler (GtkWidget *widget, GdkEvent *event) 
    273 {        
    274         g_return_val_if_fail (event != NULL, FALSE); 
    275          
    276          
    277         if (G_UNLIKELY (event->type == GDK_BUTTON_PRESS)) 
    278         { 
    279                 GtkMenu *menu; 
    280                 GdkEventButton *event_button; 
    281  
    282                 menu = GTK_MENU (widget); 
    283                 g_return_val_if_fail (widget != NULL, FALSE); 
    284                 g_return_val_if_fail (GTK_IS_MENU (widget), FALSE); 
    285  
    286                 event_button = (GdkEventButton *) event; 
    287                 if (G_LIKELY (event_button->button == 3)) 
    288                 { 
    289                         gtk_menu_popup (menu, NULL, NULL, NULL, NULL,  
    290                                           event_button->button, event_button->time); 
    291                         return TRUE; 
    292                 } 
    293         } 
    294          
    295         return FALSE; 
    296 } 
    297  
    298 static void  
    299 tny_moz_embed_msg_view_set_msg (TnyMsgView *self, TnyMsg *msg) 
    300 { 
    301         TnyMozEmbedMsgViewPriv *priv = TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE (self); 
    302  
    303      
    304         if (G_LIKELY (priv->msg)) 
    305                 g_object_unref (G_OBJECT (priv->msg)); 
    306         priv->msg = NULL; 
    307      
    308         if (msg) 
    309         { 
    310                 g_object_ref (G_OBJECT (msg)); 
    311                 priv->msg = msg; 
    312                 reload_msg (self); 
    313         } 
    314 } 
    315  
    316 static void 
    317 tny_moz_embed_msg_view_clear (TnyMsgView *self) 
    318 { 
    319         TnyMozEmbedMsgViewPriv *priv = TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE (self); 
    320  
    321         GtkTextBuffer *buffer = gtk_text_view_get_buffer (priv->textview); 
    322         gtk_widget_hide (priv->attachview_sw); 
    323         gtk_text_buffer_set_text (buffer, "", 0); 
    324         tny_header_view_clear (priv->headerview); 
    325         gtk_widget_hide (GTK_WIDGET (priv->headerview)); 
    326      
    327         return; 
    328 } 
    32939 
    33040/** 
     
    34757tny_moz_embed_msg_view_instance_init (GTypeInstance *instance, gpointer g_class) 
    34858{ 
    349         TnyMozEmbedMsgView *self = (TnyMozEmbedMsgView *)instance; 
    350         TnyMozEmbedMsgViewPriv *priv = TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE (self); 
    351         GtkWidget *vbox = gtk_vbox_new (FALSE, 1); 
    352         GtkMenu *menu = GTK_MENU (gtk_menu_new ()); 
    353         GtkWidget *mitem = gtk_menu_item_new_with_mnemonic ("Save _As"); 
    354  
    355         priv->save_strategy = NULL; 
    356         priv->msg = NULL; 
    357      
    358         gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (self), NULL); 
    359         gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (self), NULL); 
    360  
    361         gtk_widget_show (mitem); 
    362  
    363         g_signal_connect (G_OBJECT (mitem), "activate",  
    364                 G_CALLBACK (tny_moz_embed_msg_view_save_as_activated), self); 
    365  
    366         gtk_menu_shell_append (GTK_MENU_SHELL (menu), mitem); 
    367  
    368         priv->attachview_sw = gtk_scrolled_window_new (NULL, NULL); 
    369  
    370         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (self),  
    371                         GTK_SHADOW_NONE); 
    372         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self), 
    373                         GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 
    374         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->attachview_sw),  
    375                         GTK_SHADOW_NONE); 
    376         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->attachview_sw), 
    377                         GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); 
    378  
    379         priv->attachview = GTK_ICON_VIEW (gtk_icon_view_new ()); 
    380  
    381         gtk_icon_view_set_selection_mode (priv->attachview, GTK_SELECTION_SINGLE); 
    382  
    383         g_signal_connect_swapped (G_OBJECT (priv->attachview), "button_press_event", 
    384                 G_CALLBACK (tny_moz_embed_msg_view_popup_handler), menu); 
    385  
    386         gtk_icon_view_set_text_column (priv->attachview,  
    387                 TNY_GTK_ATTACH_LIST_MODEL_FILENAME_COLUMN); 
    388  
    389         gtk_icon_view_set_pixbuf_column (priv->attachview,  
    390                 TNY_GTK_ATTACH_LIST_MODEL_PIXBUF_COLUMN); 
    391  
    392         gtk_icon_view_set_columns (priv->attachview, -1); 
    393         gtk_icon_view_set_item_width (priv->attachview, 100); 
    394         gtk_icon_view_set_column_spacing (priv->attachview, 10); 
    395  
    396         priv->headerview = tny_gtk_header_view_new (); 
    397  
    398         priv->textview = GTK_TEXT_VIEW (gtk_text_view_new ()); 
    399         priv->htmlview = GTK_MOZ_EMBED (gtk_moz_embed_new ()); 
    400  
    401         gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->headerview), FALSE, FALSE, 0); 
    402  
    403         gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->htmlview), TRUE, TRUE, 0); 
    404         gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (priv->textview), TRUE, TRUE, 0);         
    405  
    406         gtk_box_pack_start (GTK_BOX (vbox), priv->attachview_sw, FALSE, TRUE, 0); 
    407  
    408         gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (self),  
    409                         GTK_WIDGET (vbox)); 
    410  
    411         gtk_container_add (GTK_CONTAINER (priv->attachview_sw), GTK_WIDGET (priv->attachview)); 
    412  
    413         gtk_widget_show (GTK_WIDGET (vbox)); 
    414  
    415         gtk_widget_hide (GTK_WIDGET (priv->htmlview)); 
    416         gtk_widget_show (GTK_WIDGET (priv->textview)); 
    417  
    418         gtk_widget_hide (GTK_WIDGET (priv->headerview)); 
    419         gtk_widget_show (GTK_WIDGET (priv->attachview)); 
    420  
    42159        return; 
    42260} 
     
    42563tny_moz_embed_msg_view_finalize (GObject *object) 
    42664{ 
    427         TnyMozEmbedMsgView *self = (TnyMozEmbedMsgView *)object;         
    428         TnyMozEmbedMsgViewPriv *priv = TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE (self); 
    429  
    430         if (G_LIKELY (priv->msg)) 
    431                 g_object_unref (G_OBJECT (priv->msg)); 
    432         priv->msg = NULL; 
    433      
    434         if (G_LIKELY (priv->save_strategy)) 
    435                 g_object_unref (G_OBJECT (priv->save_strategy)); 
    436         priv->save_strategy = NULL; 
    437      
    438         /* priv->headerview will be destroyed as a GtkObject */ 
    439      
    44065        (*parent_class->finalize) (object); 
    44166 
     
    44368} 
    44469 
     70static TnyMimePartView* 
     71tny_moz_embed_msg_view_create_mime_part_view_for (TnyMsgView *self, TnyMimePart *part) 
     72{ 
     73        TnyMozEmbedMsgViewPriv *priv = TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE (self); 
     74        TnyMimePartView *retval = NULL; 
     75 
     76        if (tny_mime_part_content_type_is (part, "text/html")) 
     77        { 
     78                retval = tny_moz_embed_html_mime_part_view_new (priv->save_strategy); 
     79                gtk_box_pack_start (GTK_BOX (TNY_GTK_MSG_VIEW (self)->viewers), GTK_WIDGET (retval), TRUE, TRUE, 0); 
     80                gtk_widget_show (GTK_WIDGET (retval)); 
     81        } 
     82 
     83        if (!retval) 
     84                retval = TNY_MOZ_EMBED_MSG_VIEW_GET_CLASS (self)->create_mime_part_view_for_orig_func (self, part); 
     85         
     86        return retval; 
     87} 
     88 
    44589static void 
    446 tny_msg_view_init (gpointer g, gpointer iface_data
     90tny_moz_embed_msg_view_set_save_strategy (TnyMsgView *self, TnySaveStrategy *strategy
    44791{ 
    448         TnyMsgViewIface *klass = (TnyMsgViewIface *)g; 
    449  
    450         klass->set_msg_func = tny_moz_embed_msg_view_set_msg; 
    451         klass->set_save_strategy_func = tny_mozembed_msg_view_set_save_strategy; 
    452         klass->set_unavailable_func = tny_mozembed_msg_view_set_unavailable; 
    453         klass->clear_func = tny_moz_embed_msg_view_clear; 
    454  
     92        TnyMozEmbedMsgViewPriv *priv = TNY_MOZ_EMBED_MSG_VIEW_GET_PRIVATE (self); 
     93        priv->save_strategy = strategy; 
     94        TNY_MOZ_EMBED_MSG_VIEW_GET_CLASS (self)->set_save_strategy_orig_func (self, strategy); 
     95         
    45596        return; 
    45697} 
     98 
    45799 
    458100static void  
     
    465107 
    466108        object_class->finalize = tny_moz_embed_msg_view_finalize; 
     109 
     110        /* Method overloading */ 
     111        class->create_mime_part_view_for_orig_func = TNY_GTK_MSG_VIEW_CLASS (class)->create_mime_part_view_for_func; 
     112        class->set_save_strategy_orig_func = TNY_GTK_MSG_VIEW_CLASS (class)->set_save_strategy_func; 
     113        TNY_GTK_MSG_VIEW_CLASS (class)->create_mime_part_view_for_func = tny_moz_embed_msg_view_create_mime_part_view_for; 
     114        TNY_GTK_MSG_VIEW_CLASS (class)->set_save_strategy_func = tny_moz_embed_msg_view_set_save_strategy; 
    467115 
    468116        g_type_class_add_private (object_class, sizeof (TnyMozEmbedMsgViewPriv)); 
     
    491139                }; 
    492140 
    493                 static const GInterfaceInfo tny_msg_view_info =  
    494                 { 
    495                   (GInterfaceInitFunc) tny_msg_view_init, /* interface_init */ 
    496                   NULL,         /* interface_finalize */ 
    497                   NULL          /* interface_data */ 
    498                 }; 
    499  
    500                 type = g_type_register_static (GTK_TYPE_SCROLLED_WINDOW, 
     141                type = g_type_register_static (TNY_TYPE_GTK_MSG_VIEW, 
    501142                        "TnyMozEmbedMsgView", 
    502143                        &info, 0); 
    503  
    504                 g_type_add_interface_static (type, TNY_TYPE_MSG_VIEW,  
    505                         &tny_msg_view_info); 
    506  
    507144        }