* cleanup icon handling a bit
[modest] / src / widgets / modest-msg-view.c
index 98abca0..ae6112b 100644 (file)
@@ -52,10 +52,12 @@ static void     modest_msg_view_class_init   (ModestMsgViewClass *klass);
 static void     modest_msg_view_init         (ModestMsgView *obj);
 static void     modest_msg_view_finalize     (GObject *obj);
 static void     modest_msg_view_destroy     (GtkObject *obj);
+static void     set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void     get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
 
 /* headers signals */
 static void on_recpt_activated (ModestMailHeaderView *header_view, const gchar *address, ModestMsgView *msg_view);
-static void on_attachment_activated (ModestAttachmentsView * att_view, gint index, gpointer);
+static void on_attachment_activated (ModestAttachmentsView * att_view, TnyMimePart *mime_part, gpointer userdata);
 
 /* GtkHtml signals */
 static gboolean on_link_clicked (GtkWidget *widget, const gchar *uri, ModestMsgView *msg_view);
@@ -92,6 +94,14 @@ enum {
        LAST_SIGNAL
 };
 
+/* list properties */
+enum {
+       PROP_0,
+       PROP_HADJUSTMENT,
+       PROP_VADJUSTMENT,
+       PROP_SHADOW_TYPE
+};
+
 typedef struct _ModestMsgViewPrivate ModestMsgViewPrivate;
 struct _ModestMsgViewPrivate {
        GtkWidget   *gtkhtml;
@@ -103,10 +113,12 @@ struct _ModestMsgViewPrivate {
        /* embedded elements */
        GtkWidget   *headers_box;
        GtkWidget   *html_scroll;
+       GtkWidget   *attachments_box;
 
        /* internal adjustments for set_scroll_adjustments */
        GtkAdjustment *hadj;
        GtkAdjustment *vadj;
+       GtkShadowType shadow_type;
 
        /* gdk windows for drawing */
        GdkWindow *view_window;
@@ -162,6 +174,8 @@ modest_msg_view_class_init (ModestMsgViewClass *klass)
 
        parent_class            = g_type_class_peek_parent (klass);
        gobject_class->finalize = modest_msg_view_finalize;
+       gobject_class->set_property = set_property;
+       gobject_class->get_property = get_property;
        gtkobject_class->destroy = modest_msg_view_destroy;
 
        widget_class->realize = realize;
@@ -177,6 +191,31 @@ modest_msg_view_class_init (ModestMsgViewClass *klass)
 
        g_type_class_add_private (gobject_class, sizeof(ModestMsgViewPrivate));
 
+       g_object_class_install_property (gobject_class,
+                                        PROP_HADJUSTMENT,
+                                        g_param_spec_object ("hadjustment", 
+                                                             _("Horizontal adjustment"),
+                                                             _("GtkAdjustment with information of the horizontal visible position"),
+                                                             GTK_TYPE_ADJUSTMENT,
+                                                             G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+
+       g_object_class_install_property (gobject_class,
+                                        PROP_VADJUSTMENT,
+                                        g_param_spec_object ("vadjustment", 
+                                                             _("Vertical adjustment"),
+                                                             _("GtkAdjustment with information of the vertical visible position"),
+                                                             GTK_TYPE_ADJUSTMENT,
+                                                             G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+
+       g_object_class_install_property (gobject_class,
+                                        PROP_SHADOW_TYPE,
+                                        g_param_spec_enum ("shadow_type", 
+                                                           _("Shadow type"),
+                                                           _("Kind of shadow that's shown around the view"),
+                                                           GTK_TYPE_SHADOW_TYPE,
+                                                           GTK_SHADOW_IN,
+                                                           G_PARAM_READABLE | G_PARAM_WRITABLE ));
+
        signals[LINK_CLICKED_SIGNAL] =
                g_signal_new ("link_clicked",
                              G_TYPE_FROM_CLASS (gobject_class),
@@ -192,8 +231,8 @@ modest_msg_view_class_init (ModestMsgViewClass *klass)
                              G_SIGNAL_RUN_FIRST,
                              G_STRUCT_OFFSET(ModestMsgViewClass, attachment_clicked),
                              NULL, NULL,
-                             g_cclosure_marshal_VOID__POINTER,
-                             G_TYPE_NONE, 1, G_TYPE_INT);
+                             g_cclosure_marshal_VOID__OBJECT,
+                             G_TYPE_NONE, 1, G_TYPE_OBJECT);
        
        signals[LINK_HOVER_SIGNAL] =
                g_signal_new ("link_hover",
@@ -226,6 +265,55 @@ modest_msg_view_class_init (ModestMsgViewClass *klass)
 }
 
 static void
+set_property (GObject *object, 
+             guint prop_id, 
+             const GValue *value, 
+             GParamSpec *pspec)
+{
+       ModestMsgView *msg_view = MODEST_MSG_VIEW (object);
+
+       switch (prop_id) {
+       case PROP_HADJUSTMENT:
+               modest_msg_view_set_hadjustment (msg_view, g_value_get_object (value));
+               break;
+       case PROP_VADJUSTMENT:
+               modest_msg_view_set_vadjustment (msg_view, g_value_get_object (value));
+               break;
+       case PROP_SHADOW_TYPE:
+               modest_msg_view_set_shadow_type (msg_view, g_value_get_enum (value));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+get_property (GObject *object, 
+             guint prop_id, 
+             GValue *value, 
+             GParamSpec *pspec)
+{
+       ModestMsgView *msg_view = MODEST_MSG_VIEW (object);
+       ModestMsgViewPrivate *priv = MODEST_MSG_VIEW_GET_PRIVATE (msg_view);
+
+       switch (prop_id) {
+       case PROP_HADJUSTMENT:
+               g_value_set_object (value, priv->hadj);
+               break;
+       case PROP_VADJUSTMENT:
+               g_value_set_object (value, priv->vadj);
+               break;
+       case PROP_SHADOW_TYPE:
+               g_value_set_enum (value, priv->shadow_type);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
 disconnect_hadjustment (ModestMsgView *msg_view)
 {
        ModestMsgViewPrivate *priv = MODEST_MSG_VIEW_GET_PRIVATE (msg_view);
@@ -254,12 +342,18 @@ get_view_allocation (ModestMsgView *msg_view, GtkAllocation *allocation)
 {
        /* This method gets the allocation of the widget in parent widget. It's the
           real position and size of the widget */
+       ModestMsgViewPrivate *priv = MODEST_MSG_VIEW_GET_PRIVATE (msg_view);
        
        allocation->x = 0;
        allocation->y = 0;
 
-       allocation->width = MAX (1, GTK_WIDGET (msg_view)->allocation.width);
-       allocation->height = MAX (1, GTK_WIDGET (msg_view)->allocation.height);
+       if (priv->shadow_type != GTK_SHADOW_NONE) {
+               allocation->x = GTK_WIDGET (msg_view)->style->xthickness;
+               allocation->y = GTK_WIDGET (msg_view)->style->ythickness;
+       }
+
+       allocation->width = MAX (1, (GTK_WIDGET (msg_view)->allocation.width) - allocation->x * 2);
+       allocation->height = MAX (1, (GTK_WIDGET (msg_view)->allocation.height) - allocation->y * 2);
 
 }
 
@@ -488,7 +582,7 @@ expose (GtkWidget *widget,
                priv = MODEST_MSG_VIEW_GET_PRIVATE (msg_view);
                if (event->window == widget->window) {
                        gtk_paint_shadow (widget->style, widget->window,
-                                         GTK_STATE_NORMAL, GTK_SHADOW_NONE,
+                                         GTK_STATE_NORMAL, priv->shadow_type,
                                          &event->area, widget, "msgview",
                                          0,0,-1,-1);
                } else if (event->window == priv->headers_window) {
@@ -574,16 +668,24 @@ size_allocate (GtkWidget *widget,
        ModestMsgView *msg_view = MODEST_MSG_VIEW (widget);
        ModestMsgViewPrivate *priv = MODEST_MSG_VIEW_GET_PRIVATE (msg_view);
        gboolean hadj_value_changed, vadj_value_changed;
-       GtkAllocation headers_allocation, html_allocation;
+       GtkAllocation headers_allocation, html_allocation, view_allocation;
        GtkAdjustment *html_vadj;
 
+       if (GTK_WIDGET_MAPPED (widget) &&
+           priv->shadow_type != GTK_SHADOW_NONE && 
+           (allocation->width != widget->allocation.width ||
+            allocation->height != widget->allocation.height))
+               gdk_window_invalidate_rect (widget->window, NULL, FALSE);
+
        widget->allocation = *allocation;
        set_hadjustment_values (msg_view, &hadj_value_changed);
        set_vadjustment_values (msg_view, &vadj_value_changed);
 
+       get_view_allocation (msg_view, &view_allocation);
+
        headers_allocation.x = 0;
        headers_allocation.y = 0;
-       headers_allocation.width = allocation->width;
+       headers_allocation.width = view_allocation.width;
        if (priv->headers_box)
                headers_allocation.height = GTK_WIDGET (priv->headers_box)->requisition.height;
        else
@@ -593,19 +695,16 @@ size_allocate (GtkWidget *widget,
 
        html_allocation.x = 0;
        html_allocation.y = headers_allocation.height;
-       html_allocation.width = allocation->width;
+       html_allocation.width = view_allocation.width;
        html_allocation.height = MAX ((gint) html_vadj->upper, (gint)(priv->vadj->upper - headers_allocation.height));
 
        if (GTK_WIDGET_REALIZED (widget)) {
-               GtkAllocation view_allocation;
                gdk_window_move_resize (widget->window,
                                        allocation->x,
                                        allocation->y,
                                        allocation->width,
                                        allocation->height);
 
-               get_view_allocation (msg_view, &view_allocation);
-
                gdk_window_move_resize (priv->view_window,
                                        view_allocation.x,
                                        view_allocation.y,
@@ -734,6 +833,7 @@ modest_msg_view_init (ModestMsgView *obj)
 
        priv->hadj = NULL;
        priv->vadj = NULL;
+       priv->shadow_type = GTK_SHADOW_IN;
        priv->view_window = NULL;
        priv->headers_window = NULL;
        priv->html_window = NULL;
@@ -758,7 +858,6 @@ modest_msg_view_init (ModestMsgView *obj)
        gtk_widget_set_no_show_all (priv->mail_header_view, TRUE);
 
        priv->attachments_view        = GTK_WIDGET(modest_attachments_view_new (NULL));
-       gtk_widget_set_no_show_all (priv->attachments_view, TRUE);
 
        priv->sig1 = g_signal_connect (G_OBJECT(priv->gtkhtml), "link_clicked",
                                       G_CALLBACK(on_link_clicked), obj);
@@ -807,7 +906,6 @@ modest_msg_view_finalize (GObject *obj)
 static void
 modest_msg_view_destroy (GtkObject *obj)
 {      
-       ModestMsgViewPrivate *priv = MODEST_MSG_VIEW_GET_PRIVATE (obj);
        disconnect_vadjustment (MODEST_MSG_VIEW(obj));
        disconnect_hadjustment (MODEST_MSG_VIEW(obj));
 
@@ -863,6 +961,8 @@ modest_msg_view_set_hadjustment (ModestMsgView *msg_view, GtkAdjustment *hadj)
                gtk_adjustment_value_changed (hadj);
        else
                adjustment_value_changed (hadj, msg_view);
+
+       g_object_notify (G_OBJECT (msg_view), "hadjustment");
 }
 
 void
@@ -890,6 +990,53 @@ modest_msg_view_set_vadjustment (ModestMsgView *msg_view, GtkAdjustment *vadj)
                gtk_adjustment_value_changed (vadj);
        else
                adjustment_value_changed (vadj, msg_view);
+
+       g_object_notify (G_OBJECT (msg_view), "vadjustment");
+}
+
+/** 
+ * modest_msg_view_set_shadow_type:
+ * @msg_view: a #ModestMsgView.
+ * @shadow_type: new shadow type.
+ *
+ * Sets a shadow type of the message view.
+ **/ 
+void
+modest_msg_view_set_shadow_type (ModestMsgView *msg_view,
+                                GtkShadowType shadow_type)
+{
+       ModestMsgViewPrivate *priv;
+       g_return_if_fail (MODEST_IS_MSG_VIEW (msg_view));
+
+       priv = MODEST_MSG_VIEW_GET_PRIVATE (msg_view);
+       
+       if (priv->shadow_type != shadow_type) {
+               priv->shadow_type = shadow_type;
+               
+               if (GTK_WIDGET_VISIBLE (msg_view)) {
+                       gtk_widget_size_allocate (GTK_WIDGET (msg_view), &(GTK_WIDGET (msg_view)->allocation));
+                       gtk_widget_queue_draw (GTK_WIDGET (msg_view));
+               }
+               g_object_notify (G_OBJECT (msg_view), "shadow-type");
+       }
+}
+
+/**
+ * modest_msg_view_get_shadow_type:
+ * @msg_view: a #ModestMsgView
+ *
+ * Gets the current shadow type of the #ModestMsgView.
+ *
+ * Return value: the shadow type 
+ **/
+GtkShadowType
+modest_msg_view_get_shadow_type (ModestMsgView *msg_view)
+{
+       ModestMsgViewPrivate *priv;
+       g_return_val_if_fail (MODEST_IS_MSG_VIEW (msg_view), GTK_SHADOW_NONE);
+       priv = MODEST_MSG_VIEW_GET_PRIVATE (msg_view);
+       
+       return priv->shadow_type;
 }
 
 GtkWidget*
@@ -911,8 +1058,13 @@ modest_msg_view_new (TnyMsg *msg)
        if (priv->mail_header_view)
                gtk_box_pack_start (GTK_BOX(priv->headers_box), priv->mail_header_view, FALSE, FALSE, 0);
        
-       if (priv->attachments_view)
-               gtk_box_pack_start (GTK_BOX(priv->headers_box), priv->attachments_view, FALSE, FALSE, 0);
+       if (priv->attachments_view) {
+               priv->attachments_box = (GtkWidget *) modest_mail_header_view_add_custom_header (MODEST_MAIL_HEADER_VIEW (priv->mail_header_view),
+                                                                                                _("Attachments:"), priv->attachments_view,
+                                                                                                FALSE, FALSE);
+               gtk_widget_hide_all (priv->attachments_box);
+/*             gtk_widget_set_no_show_all (priv->attachments_box, TRUE); */
+       }
 
        gtk_widget_set_parent (priv->headers_box, GTK_WIDGET (self));
 
@@ -935,18 +1087,11 @@ on_recpt_activated (ModestMailHeaderView *header_view,
 }
 
 static void
-on_attachment_activated (ModestAttachmentsView * att_view, gint index, gpointer msg_view)
+on_attachment_activated (ModestAttachmentsView * att_view, TnyMimePart *mime_part, gpointer msg_view)
 {
 
-       
-       if (index == 0) {
-               /* index is 1-based, so 0 indicates an error */
-               g_printerr ("modest: invalid attachment index: %d\n", index);
-               return;
-       }
-
        g_signal_emit (G_OBJECT(msg_view), signals[ATTACHMENT_CLICKED_SIGNAL],
-                      0, index);
+                      0, mime_part);
 }
 
 static gboolean
@@ -1148,9 +1293,9 @@ modest_msg_view_set_message (ModestMsgView *self, TnyMsg *msg)
        
        if (!msg) {
                tny_header_view_clear (TNY_HEADER_VIEW (priv->mail_header_view));
+               modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), NULL);
                gtk_widget_hide_all (priv->mail_header_view);
-               gtk_widget_hide_all (priv->attachments_view);
-               gtk_widget_set_no_show_all (priv->attachments_view, TRUE);
+               gtk_widget_hide_all (priv->attachments_box);
                gtk_widget_set_no_show_all (priv->mail_header_view, TRUE);
                set_empty_message (self);
                gtk_widget_queue_resize (GTK_WIDGET(self));
@@ -1167,16 +1312,29 @@ modest_msg_view_set_message (ModestMsgView *self, TnyMsg *msg)
        
        body = modest_tny_msg_find_body_part (msg,TRUE);
        if (body) {
+               GList *att_children;
                if (tny_mime_part_content_type_is (body, "text/html"))
                        set_html_message (self, body, msg);
                else
                        set_text_message (self, body, msg);
+
+               att_children = gtk_container_get_children (GTK_CONTAINER (priv->attachments_view));
+               if (att_children != NULL) {
+                       gtk_widget_show_all (priv->attachments_box);
+                       g_list_free (att_children);
+               } else {
+                       gtk_widget_hide_all (priv->attachments_box);
+               }
+                       
        } else 
                set_empty_message (self);
 
        gtk_widget_show (priv->gtkhtml);
+       gtk_widget_set_no_show_all (priv->attachments_box, TRUE);
        gtk_widget_show_all (priv->mail_header_view);
-       gtk_widget_show_all (priv->attachments_view);
+       gtk_widget_set_no_show_all (priv->attachments_box, FALSE);
+/*     gtk_widget_show_all (priv->attachments_box); */
+/*     gtk_widget_show_all (priv->attachments_box); */
        gtk_widget_set_no_show_all (priv->mail_header_view, TRUE);
        gtk_widget_queue_resize (GTK_WIDGET(self));
        gtk_widget_queue_draw (GTK_WIDGET(self));