* src/maemo/modest-msg-edit-window.c: added support for rich editing
authorJose Dapena Paz <jdapena@igalia.com>
Sun, 1 Apr 2007 13:03:27 +0000 (13:03 +0000)
committerJose Dapena Paz <jdapena@igalia.com>
Sun, 1 Apr 2007 13:03:27 +0000 (13:03 +0000)
  (using wpeditor library).
        * Includes support for toggling bold/italics, adding bullet lists,
          inserting images, changing font color, size and face.
* src/maemo/modest-icon-names.h:
        * Added icon for bullet lists in edit window.
* src/gnome/modest-icon-names.h:
        * Added icon for bullet lists in edit window.
* src/maemo/ui/modest-msg-edit-window-ui.xml:
        * Added menu formatting actions (inserting images, alignments, background
          color, bullet lists).
        * Added toolbar formatting actions (bold, italics, bullet lists), and
          a place holder for font properties elements in toolbar.
* src/maemo/ui/modest-msg-view-window-ui.xml:
        * Added menu actions for messages (not implemented yet, includes replying,
          deleting, and others.
* src/gnome/modest-msg-edit-window.c:
        * Modified methods to send mail to support the new API supporting rich text
          editting. Anyway the Gnome client does not support this yet.
* src/widgets/modest-mail-header-view.[ch]:
        * Now date/time field separates the Time: value as a new field, and it's
          always shown independent from being a mail sent another day.
        * Preliminar support for showing priority icons in subjects. Now subject is
          showin as a GTKHBox, with a first part for priority icon (currently not used)
          and a second part for the subject itself.
        * Changed order of header fields (recipients in special) to accomplish the
          UI specs.
        * Added new method to add custom headers (header data implemented with a widget).
          This is used for adding attachments list as a header.
* src/widgets/modest-msg-edit-window.h:
        * Added support for exposing rich text editing format.
* Added src/widgets/modest-attachment-view.[ch]:
        * Widget showing an only attachment, with its size and icon. It's a refactoring
          of previous attachments view, splitting in specific widgets each attachment.
* src/widgets/modest-attachments-view.[ch]: big rework of this widget.
        * Now the "activated" signal passes a TnyMimePart instead of an attachmetn index.
        * Now it's a GtkVBox with the attachments one per line. They include the new
          ModestAttachmentView for showing each mime part.
* src/widgets/modest-msg-edit-window-ui.h:
        * Added support for rich editing actions.
* src/widgets/Makefile.am:
        * Added compilation of new ModestAttachmentView widget.
* src/widgets/modest-msg-view.[ch]:
        * Now attachments signal returns a TnyMimePart instead of an index.
        * Now attachments are shown as a header, using the new modest_header_view_add_custom_header
          method.
* src/modest-tny-msg.[ch]:
        * Support for sending html-formatted mails.
* src/modest-mail-operations.[ch]:
        * Now ..._send_new_mail gets both plain text and html versions of the message,
          to allow sending rich text messages.
* src/modest-runtime.c:
        * Add bullet list icons.
* src/modest-main.c:
        * Use the new _send_new_mail api supporting rich text messages (sends a NULL html
          field, as the command line API is only supporting plain text sends).
* src/modest-ui-actions.[ch]:
        * Update on_msg_attachment_clicked, as now it gets a TnyMimePart
          instead of an index.
        * (modest_ui_actions_on_send): updated to handle rich text messages
          (those with html and raw text versions).
        * Methods for rich text editor actions: ..._on_toggle_bold,
          ..._on_toggle_italics, ..._on_toggle_bullets, ..._on_change_justify,
          ..._on_select_editor_color, ..._on_select_editor_background_color,
          ..._on_insert_image.

pmo-trunk-r1469

25 files changed:
src/gnome/modest-icon-names.h
src/gnome/modest-msg-edit-window.c
src/maemo/modest-icon-names.h
src/maemo/modest-msg-edit-window.c
src/maemo/ui/modest-msg-edit-window-ui.xml
src/maemo/ui/modest-msg-view-window-ui.xml
src/modest-mail-operation.c
src/modest-mail-operation.h
src/modest-main.c
src/modest-runtime.c
src/modest-tny-msg.c
src/modest-tny-msg.h
src/modest-ui-actions.c
src/modest-ui-actions.h
src/widgets/Makefile.am
src/widgets/modest-attachment-view.c [new file with mode: 0644]
src/widgets/modest-attachment-view.h [new file with mode: 0644]
src/widgets/modest-attachments-view.c
src/widgets/modest-attachments-view.h
src/widgets/modest-mail-header-view.c
src/widgets/modest-mail-header-view.h
src/widgets/modest-msg-edit-window-ui.h
src/widgets/modest-msg-edit-window.h
src/widgets/modest-msg-view.c
src/widgets/modest-msg-view.h

index 6fddd7d..75f5833 100644 (file)
@@ -75,6 +75,7 @@
 /* #define  MODEST_TOOLBAR_ICON_NEXT           PIXMAP_PREFIX "forward.png" */
 /* #define  MODEST_TOOLBAR_ICON_PREV           PIXMAP_PREFIX "back.png" */
 #define  MODEST_TOOLBAR_ICON_STOP              PIXMAP_PREFIX "stock-stop.png"
+#define  MODEST_TOOLBAR_ICON_FORMAT_BULLETS     PIXMAP_PREFIX "qgn_list_gene_bullets"
 
 /* Stock icon names */
 #define  MODEST_STOCK_MAIL_SEND           "modest-stock-mail-send"
index 2ed3095..62d56a0 100644 (file)
@@ -402,7 +402,9 @@ modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
        data->cc      =  (gchar*) gtk_entry_get_text (GTK_ENTRY(priv->cc_field));
        data->bcc     =  (gchar*) gtk_entry_get_text (GTK_ENTRY(priv->bcc_field));
        data->subject =  (gchar*) gtk_entry_get_text (GTK_ENTRY(priv->subject_field));
-       data->body    =  gtk_text_buffer_get_text (buf, &b, &e, FALSE);
+       data->plain_body    =  gtk_text_buffer_get_text (buf, &b, &e, FALSE);
+       /* No rich supported yet, then html body is NULL */
+       data->html_body = NULL;
 
        return data;
 }
@@ -414,6 +416,76 @@ modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
        g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
 
        g_free (data->from);
-       g_free (data->body);
+       g_free (data->plain_body);
+       g_free (data->html_body);
        g_slice_free (MsgData, data);
 }
+
+/* Rich formatting API functions */
+ModestMsgEditFormat
+modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
+{
+       return MODEST_MSG_EDIT_FORMAT_TEXT;
+}
+
+void
+modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
+                                  ModestMsgEditFormat format)
+{
+       switch (format) {
+       case MODEST_MSG_EDIT_FORMAT_TEXT:
+               break;
+       case MODEST_MSG_EDIT_FORMAT_HTML:
+               g_message ("HTML format not supported in Gnome ModestMsgEditWindow");
+               break;
+       default:
+               break;
+       }
+}
+
+ModestMsgEditFormatState *
+modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
+{
+       ModestMsgEditFormatState *format_state;
+
+       g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
+
+       format_state = g_new0 (ModestMsgEditFormatState, 1);
+
+       return format_state;
+}
+
+void
+modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self, 
+                                        const ModestMsgEditFormatState *format_state)
+{
+       g_return_if_fail (MODEST_MSG_EDIT_WINDOW (self));
+
+       /* Ends silently as set_format_state should do nothing when edit window format
+          is not HTML */
+       return;
+}
+
+void
+modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
+{
+       g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
+
+       g_message ("Select color operation is not supported");
+}
+
+void
+modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
+{
+       g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
+
+       g_message ("Select background color operation is not supported");
+}
+
+void
+modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
+{
+       g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
+
+       g_message ("Insert image operation is not supported");
+}
index 3dd8b1e..4ce0b0b 100644 (file)
@@ -71,6 +71,7 @@
 #define  MODEST_TOOLBAR_ICON_REPLY_ALL         "qgn_toolb_messagin_replytoall"
 #define  MODEST_TOOLBAR_ICON_FORWARD           "qgn_toolb_messagin_forward"
 #define  MODEST_TOOLBAR_ICON_DELETE            "qgn_toolb_messagin_delete"
+#define  MODEST_TOOLBAR_ICON_FORMAT_BULLETS     "qgn_list_gene_bullets"
 
 /* Stock icon names */
 #define  MODEST_STOCK_MAIL_SEND    "modest-stock-mail-send"
index 3ff45da..dc6cf2f 100644 (file)
@@ -27,6 +27,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <glib/gi18n.h>
+#include <fcntl.h>
+#include <glib/gstdio.h>
 #include <tny-account-store.h>
 
 #include <gtk/gtk.h>
 #include "modest-tny-platform-factory.h"
 #include "modest-tny-msg.h"
 #include <tny-simple-list.h>
+#include <wptextview.h>
+#include <wptextbuffer.h>
+#include <hildon-widgets/hildon-color-selector.h>
+#include <hildon-widgets/hildon-color-button.h>
+#include <hildon-widgets/hildon-file-chooser-dialog.h>
+
+#define DEFAULT_FONT_SIZE 3
+#define DEFAULT_FONT 2
+#define DEFAULT_SIZE_COMBOBOX_WIDTH 80
 
 static void  modest_msg_edit_window_class_init   (ModestMsgEditWindowClass *klass);
 static void  modest_msg_edit_window_init         (ModestMsgEditWindow *obj);
 static void  modest_msg_edit_window_finalize     (GObject *obj);
 
+static void  text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
+static void  modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
+                                                        gpointer userdata);
+static void  modest_msg_edit_window_size_combobox_change (ModestMsgEditWindow *window,
+                                                         gpointer userdata);
+static void  modest_msg_edit_window_font_combobox_change (ModestMsgEditWindow *window,
+                                                         gpointer userdata);
+static void  modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
+
 /* list my signals */
 enum {
        /* MY_SIGNAL_1, */
@@ -66,6 +86,15 @@ struct _ModestMsgEditWindowPrivate {
        GtkWidget   *cc_field;
        GtkWidget   *bcc_field;
        GtkWidget   *subject_field;
+
+       GtkTextBuffer *text_buffer;
+
+       GtkWidget   *font_color_button;
+       GtkWidget   *size_combobox;
+       GtkWidget   *font_combobox;
+
+       gint last_cid;
+       GList *attachments;
 };
 
 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
@@ -97,6 +126,8 @@ modest_msg_edit_window_get_type (void)
                my_type = g_type_register_static (MODEST_TYPE_WINDOW,
                                                  "ModestMsgEditWindow",
                                                  &my_info, 0);
+
+               wp_text_buffer_library_init ();
        }
        return my_type;
 }
@@ -125,6 +156,8 @@ modest_msg_edit_window_init (ModestMsgEditWindow *obj)
        priv->cc_field      = NULL;
        priv->bcc_field     = NULL;
        priv->subject_field = NULL;
+       priv->attachments = NULL;
+       priv->last_cid = 0;
 }
 
 
@@ -183,6 +216,7 @@ init_window (ModestMsgEditWindow *obj)
        GtkWidget *to_button, *cc_button, *bcc_button; 
        GtkWidget *header_table;
        GtkWidget *main_vbox;
+       GtkWidget *body_scroll;
        ModestMsgEditWindowPrivate *priv;
        ModestPairList *protos;
 
@@ -217,12 +251,25 @@ init_window (ModestMsgEditWindow *obj)
        gtk_table_attach_defaults (GTK_TABLE(header_table), priv->bcc_field,    1,2,3,4);
        gtk_table_attach_defaults (GTK_TABLE(header_table), priv->subject_field,1,2,4,5);
 
-       priv->msg_body = gtk_text_view_new ();
+       priv->msg_body = wp_text_view_new ();
+       gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
+       priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
+       g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
+       wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
+       gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE);
+       wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
+       g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
+                         G_CALLBACK (text_buffer_refresh_attributes), obj);
+
+       body_scroll = gtk_scrolled_window_new (NULL, NULL);
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (body_scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (body_scroll), GTK_SHADOW_IN);
+       gtk_container_add (GTK_CONTAINER (body_scroll), priv->msg_body);
        
        main_vbox = gtk_vbox_new  (FALSE, 6);
 
        gtk_box_pack_start (GTK_BOX(main_vbox), header_table, FALSE, FALSE, 6);
-       gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 6);
+       gtk_box_pack_start (GTK_BOX(main_vbox), body_scroll, TRUE, TRUE, 6);
 
        gtk_widget_show_all (GTK_WIDGET(main_vbox));
        
@@ -277,15 +324,13 @@ menubar_to_menu (GtkUIManager *ui_manager)
 }
 
 
-#if 0
 static void
 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
 {
        TnyHeader *header;
-       GtkTextBuffer *buf;
-       const gchar *to, *cc, *bcc, *subject;
+       const gchar *to, *cc, *bcc, *subject, *body;
        ModestMsgEditWindowPrivate *priv;
-
+       
        g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
        g_return_if_fail (TNY_IS_MSG (msg));
 
@@ -306,10 +351,29 @@ set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
        if (subject)
                gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);   
        
-       buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW(priv->msg_body));
-       gtk_text_buffer_set_text (buf,
-                                 (const gchar *) modest_tny_msg_get_body (msg, FALSE),
-                                 -1);
+       gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE);
+       wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
+       body = modest_tny_msg_get_body (msg, FALSE);
+       if ((body!=NULL) && (body[0] != '\0')) {
+               wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
+               wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
+                                                   (gchar *) body,
+                                                   -1);
+               wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
+       } else {
+               WPTextBufferFormat fmt = {0};
+
+               fmt.font_size = DEFAULT_FONT_SIZE;
+               fmt.font = DEFAULT_FONT;
+               fmt.rich_text = 1;
+               fmt.text_position = TEXT_POSITION_NORMAL;
+               fmt.justification = 0;
+               fmt.cs.font_size = 1;
+               fmt.cs.font = 1;
+               fmt.cs.text_position = 1;
+               fmt.cs.justification = 1;
+               wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &fmt);
+       }
 
        /* TODO: lower priority, select in the From: combo to the
           value that comes from msg <- not sure, should it be
@@ -317,9 +381,62 @@ set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
        
        /* TODO: set attachments */
 }
-#endif
 
-       
+static void
+modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
+{
+       ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
+       ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
+       GtkWidget *font_placeholder;
+       GtkWidget *tool_item;
+       gint insert_index;
+       gint size_index;
+       gint font_index;
+
+       /* Toolbar */
+       parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
+       hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
+
+       /* should we hide the toolbar? */
+       if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
+               gtk_widget_hide (parent_priv->toolbar);
+
+       /* Font management toolbar elements */
+       font_placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
+       insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(font_placeholder));
+
+       /* font color */
+       tool_item = GTK_WIDGET (gtk_tool_item_new ());
+       priv->font_color_button = hildon_color_button_new ();
+       gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
+       gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
+       g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
+
+       /* font_size */
+       priv->size_combobox = gtk_combo_box_new_text ();
+       gtk_widget_set_size_request (priv->size_combobox, DEFAULT_SIZE_COMBOBOX_WIDTH, -1);
+       for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
+               gchar size_text[5];
+               snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
+               gtk_combo_box_append_text (GTK_COMBO_BOX (priv->size_combobox), size_text);
+       }
+       gtk_combo_box_set_active (GTK_COMBO_BOX (priv->size_combobox), wp_get_font_size_index(12, 4));
+       tool_item = GTK_WIDGET (gtk_tool_item_new ());
+       gtk_container_add (GTK_CONTAINER (tool_item), priv->size_combobox);
+       gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
+       g_signal_connect_swapped (G_OBJECT (priv->size_combobox), "changed", G_CALLBACK (modest_msg_edit_window_size_combobox_change), window);
+
+       priv->font_combobox = gtk_combo_box_new_text ();
+       for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
+               gtk_combo_box_append_text (GTK_COMBO_BOX (priv->font_combobox), wp_get_font_name (font_index));
+       }
+       tool_item = GTK_WIDGET (gtk_tool_item_new ());
+       gtk_container_add (GTK_CONTAINER (tool_item), priv->font_combobox);
+       gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
+       g_signal_connect_swapped (G_OBJECT (priv->font_combobox), "changed", G_CALLBACK (modest_msg_edit_window_font_combobox_change), window);
+}
+
+
 
 ModestWindow*
 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
@@ -349,6 +466,12 @@ modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
                                             modest_msg_edit_toggle_action_entries,
                                             G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
                                             obj);
+       gtk_action_group_add_radio_actions (action_group,
+                                           modest_msg_edit_alignment_radio_action_entries,
+                                           G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
+                                           GTK_JUSTIFY_LEFT,
+                                           G_CALLBACK (modest_ui_actions_on_change_justify),
+                                           obj);
        gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
        g_object_unref (action_group);
 
@@ -365,14 +488,6 @@ modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
                                    gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
 
 
-       /* Toolbar */
-       parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
-       hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (parent_priv->toolbar));
-
-       /* should we hide the toolbar? */
-       if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
-               gtk_widget_hide (parent_priv->toolbar);
-
        
        /* Menubar */
        parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
@@ -380,7 +495,7 @@ modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
 
        /* Init window */
        init_window (MODEST_MSG_EDIT_WINDOW(obj));
-       
+
        restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
                
        gtk_window_set_title (GTK_WINDOW(obj), "Modest");
@@ -390,9 +505,40 @@ modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
                          G_CALLBACK(on_delete_event), obj);
 
        modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
+
+       modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
+
+       set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
+
+       text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
+       
        return (ModestWindow*)obj;
 }
 
+static gint
+get_formatted_data_cb (const gchar *buffer, gpointer user_data)
+{
+       GString **string_buffer = (GString **) user_data;
+
+       *string_buffer = g_string_append (*string_buffer, buffer);
+   
+       return 0;
+}
+
+static gchar *
+get_formatted_data (ModestMsgEditWindow *edit_window)
+{
+       ModestMsgEditWindowPrivate *priv;
+       GString *string_buffer = g_string_new ("");
+       
+       priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
+
+       wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
+
+       return g_string_free (string_buffer, FALSE);
+                                                                       
+}
+
 MsgData * 
 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
 {
@@ -420,7 +566,9 @@ modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
        data->cc      =  (gchar*) gtk_entry_get_text (GTK_ENTRY(priv->cc_field));
        data->bcc     =  (gchar*) gtk_entry_get_text (GTK_ENTRY(priv->bcc_field));
        data->subject =  (gchar*) gtk_entry_get_text (GTK_ENTRY(priv->subject_field));  
-       data->body    =  gtk_text_buffer_get_text (buf, &b, &e, FALSE);
+       data->plain_body =  (gchar *) gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE);
+       data->html_body  =  get_formatted_data (edit_window);
+       data->attachments = priv->attachments;
 
        return data;
 }
@@ -432,6 +580,405 @@ modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
        g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
 
        g_free (data->from);
-       g_free (data->body);
+       g_free (data->html_body);
+       g_free (data->plain_body);
        g_slice_free (MsgData, data);
 }
+
+ModestMsgEditFormat
+modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
+{
+       gboolean rich_text;
+       ModestMsgEditWindowPrivate *priv = NULL;
+       g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
+
+       priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
+
+       rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
+       if (rich_text)
+               return MODEST_MSG_EDIT_FORMAT_HTML;
+       else
+               return MODEST_MSG_EDIT_FORMAT_TEXT;
+}
+
+void
+modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
+                                  ModestMsgEditFormat format)
+{
+       ModestMsgEditWindowPrivate *priv;
+
+       g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
+       priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
+
+       switch (format) {
+       case MODEST_MSG_EDIT_FORMAT_HTML:
+               wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
+               break;
+       case MODEST_MSG_EDIT_FORMAT_TEXT:
+               wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
+               break;
+       default:
+               g_return_if_reached ();
+       }
+}
+
+ModestMsgEditFormatState *
+modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
+{
+       ModestMsgEditFormatState *format_state = NULL;
+       ModestMsgEditWindowPrivate *priv;
+       WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
+
+       g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
+       priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
+
+       wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
+
+       format_state = g_new0 (ModestMsgEditFormatState, 1);
+       format_state->bold = buffer_format->bold&0x1;
+       format_state->italics = buffer_format->italic&0x1;
+       format_state->bullet = buffer_format->bullet&0x1;
+       format_state->color = buffer_format->color;
+       format_state->font_size = buffer_format->font_size;
+       format_state->font_family = wp_get_font_name (buffer_format->font);
+       format_state->justification = buffer_format->justification;
+       g_free (buffer_format);
+
+       return format_state;
+}
+
+void
+modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
+                                        const ModestMsgEditFormatState *format_state)
+{
+       ModestMsgEditWindowPrivate *priv;
+       WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
+       WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
+       g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
+       g_return_if_fail (format_state != NULL);
+
+       priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
+       gtk_widget_grab_focus (priv->msg_body);
+       buffer_format->bold = (format_state->bold != FALSE);
+       buffer_format->italic = (format_state->italics != FALSE);
+       buffer_format->color = format_state->color;
+       buffer_format->font_size = format_state->font_size;
+       buffer_format->font = wp_get_font_index (format_state->font_family, 0);
+       buffer_format->justification = format_state->justification;
+       buffer_format->bullet = format_state->bullet;
+
+       wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
+
+       buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
+       buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
+       buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
+       buffer_format->cs.font_size =  (buffer_format->font_size != current_format->font_size);
+       buffer_format->cs.font = (buffer_format->font != current_format->font);
+       buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
+       buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
+
+       wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
+       if (buffer_format->cs.bold) {
+               wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
+       }
+       if (buffer_format->cs.italic) {
+               wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
+       }
+       if (buffer_format->cs.color) {
+               wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
+       }
+       if (buffer_format->cs.font_size) {
+               wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
+       }
+       if (buffer_format->cs.justification) {
+               switch (buffer_format->justification) {
+               case GTK_JUSTIFY_LEFT:
+                       wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
+                       break;
+               case GTK_JUSTIFY_CENTER:
+                       wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
+                       break;
+               case GTK_JUSTIFY_RIGHT:
+                       wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
+                       break;
+               default:
+                       break;
+               }
+                       
+       }
+       if (buffer_format->cs.font) {
+               wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
+       }
+       if (buffer_format->cs.bullet) {
+               wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
+       }
+/*     wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
+       wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
+
+       g_free (current_format);
+
+}
+
+static void
+toggle_action_set_active_block_notify (GtkToggleAction *action,
+                                      gboolean value)
+{
+       GSList *proxies = NULL;
+
+       for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
+            proxies != NULL; proxies = g_slist_next (proxies)) {
+               GtkWidget *widget = (GtkWidget *) proxies->data;
+               gtk_action_block_activate_from (GTK_ACTION (action), widget);
+       }
+
+       gtk_toggle_action_set_active (action, value);
+
+       for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
+            proxies != NULL; proxies = g_slist_next (proxies)) {
+               GtkWidget *widget = (GtkWidget *) proxies->data;
+               gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
+       }
+}
+
+static void
+text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
+{
+       WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
+       GtkAction *action;
+       ModestWindowPrivate *parent_priv;
+       ModestMsgEditWindowPrivate *priv;
+       
+       parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
+       priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
+
+       wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
+       
+       action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
+       toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
+
+       action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
+       toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
+
+       action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBulletedList");
+       toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
+
+       g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button), 
+                                        G_CALLBACK (modest_msg_edit_window_color_button_change),
+                                        window);
+       hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
+       g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button), 
+                                          G_CALLBACK (modest_msg_edit_window_color_button_change),
+                                          window);
+
+       g_signal_handlers_block_by_func (G_OBJECT (priv->size_combobox), 
+                                        G_CALLBACK (modest_msg_edit_window_size_combobox_change),
+                                        window);
+       gtk_combo_box_set_active (GTK_COMBO_BOX (priv->size_combobox), buffer_format->font_size);
+       g_signal_handlers_unblock_by_func (G_OBJECT (priv->size_combobox), 
+                                          G_CALLBACK (modest_msg_edit_window_size_combobox_change),
+                                          window);
+
+       g_signal_handlers_block_by_func (G_OBJECT (priv->font_combobox), 
+                                        G_CALLBACK (modest_msg_edit_window_font_combobox_change),
+                                        window);
+       gtk_combo_box_set_active (GTK_COMBO_BOX (priv->font_combobox), buffer_format->font);
+       g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_combobox), 
+                                          G_CALLBACK (modest_msg_edit_window_font_combobox_change),
+                                          window);
+
+       g_free (buffer_format);
+
+}
+
+void
+modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
+{
+       
+       WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
+       ModestMsgEditWindowPrivate *priv;
+       GtkWidget *dialog = NULL;
+       gint response;
+       const GdkColor *new_color = NULL;
+       
+       priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
+       wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
+       
+       dialog = hildon_color_selector_new (GTK_WINDOW (window));
+       hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), & (buffer_format->color));
+       g_free (buffer_format);
+
+       response = gtk_dialog_run (GTK_DIALOG (dialog));
+       switch (response) {
+       case GTK_RESPONSE_OK:
+               new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
+               break;
+       default:
+               break;
+       }
+       gtk_widget_destroy (dialog);
+
+       if (new_color != NULL)
+               wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
+
+}
+
+void
+modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
+{
+       
+       ModestMsgEditWindowPrivate *priv;
+       GtkWidget *dialog = NULL;
+       gint response;
+       const GdkColor *old_color = NULL;
+       const GdkColor *new_color = NULL;
+       
+       priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
+       old_color = wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
+       
+       dialog = hildon_color_selector_new (GTK_WINDOW (window));
+       hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), (GdkColor *) old_color);
+
+       response = gtk_dialog_run (GTK_DIALOG (dialog));
+       switch (response) {
+       case GTK_RESPONSE_OK:
+               new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
+               break;
+       default:
+               break;
+       }
+       gtk_widget_destroy (dialog);
+
+       if (new_color != NULL)
+               wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
+
+}
+
+void
+modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
+{
+       
+       ModestMsgEditWindowPrivate *priv;
+       GtkWidget *dialog = NULL;
+       gint response;
+       gchar *filename;
+       
+       priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
+       
+       dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
+
+       response = gtk_dialog_run (GTK_DIALOG (dialog));
+       switch (response) {
+       case GTK_RESPONSE_OK:
+               filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+               break;
+       default:
+               break;
+       }
+       gtk_widget_destroy (dialog);
+
+       if (filename) {
+               GdkPixbuf *pixbuf = NULL;
+               GtkTextIter position;
+               GtkTextMark *insert_mark;
+
+               pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
+               if (pixbuf) {
+                       gint image_file_id;
+                       GdkPixbufFormat *pixbuf_format;
+
+                       image_file_id = g_open (filename, O_RDONLY, 0);
+                       pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
+                       if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
+                               TnyMimePart *image_part;
+                               TnyStream *image_stream;
+                               gchar **mime_types;
+                               gchar *mime_type;
+                               gchar *basename;
+                               gchar *content_id;
+
+                               mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
+                               if ((mime_types != NULL) && (mime_types[0] != NULL)) {
+                                       mime_type = mime_types[0];
+                               } else {
+                                       mime_type = "image/unknown";
+                               }
+                               image_part = tny_platform_factory_new_mime_part
+                                       (modest_runtime_get_platform_factory ());
+                               image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
+
+                               tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
+                               g_strfreev (mime_types);
+
+                               content_id = g_strdup_printf ("%d", priv->last_cid);
+                               tny_mime_part_set_content_id (image_part, content_id);
+                               g_free (content_id);
+                               priv->last_cid++;
+
+                               basename = g_path_get_basename (filename);
+                               tny_mime_part_set_filename (image_part, basename);
+                               g_free (basename);
+                               
+                               insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
+                               gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
+                               wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
+                               priv->attachments = g_list_prepend (priv->attachments, image_part);
+                       } else if (image_file_id == -1) {
+                               close (image_file_id);
+                       }
+               }
+       }
+
+
+}
+
+static void
+modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
+                                           gpointer userdata)
+{
+       ModestMsgEditWindowPrivate *priv;
+       GdkColor *new_color;
+
+       priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
+       new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
+
+       wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
+       gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
+
+}
+
+static void
+modest_msg_edit_window_size_combobox_change (ModestMsgEditWindow *window,
+                                            gpointer userdata)
+{
+       ModestMsgEditWindowPrivate *priv;
+       gint new_size_index;
+
+       priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
+       gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
+
+       new_size_index = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->size_combobox));
+
+       if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, (gpointer) new_size_index))
+               wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
+
+       text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));;
+}
+
+static void
+modest_msg_edit_window_font_combobox_change (ModestMsgEditWindow *window,
+                                            gpointer userdata)
+{
+       ModestMsgEditWindowPrivate *priv;
+       gint new_font_index;
+
+       priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
+       gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
+
+       new_font_index = gtk_combo_box_get_active (GTK_COMBO_BOX (priv->font_combobox));
+
+       if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, (gpointer) new_font_index))
+               wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
+
+       text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
+}
index 040fdaa..27ef8fd 100644 (file)
       <menuitem name="ViewBccFieldMenu" action="ViewBccField"/>
     </menu>
 
+    <menu name="AttachmentsMenu" action="Attachments">
+      <menuitem name="InsertImageMenu" action="InsertImage"/>
+    </menu>
+
+    <menu name="FormatMenu" action="Format">
+      <menuitem name="BackgroundColorMenu" action="BackgroundColor"/>
+      <menu name="AlignmentMenu" action="Alignment">
+         <menuitem name="AlignmentLeftMenu" action="AlignmentLeft"/>
+         <menuitem name="AlignmentCenterMenu" action="AlignmentCenter"/>
+         <menuitem name="AlignmentRightMenu" action="AlignmentRight"/>
+      </menu>
+      <menuitem name="BulletedListMenu" action="ActionsBulletedList"/>
+    </menu>
+
   </menubar>
 
   <toolbar name="ToolBar">
     <toolitem action="ActionsSend"/>
+    <!--<toolitem action="ActionFontFace"/>-->
+    <!--<toolitem action="ActionFontSize"/>-->
+    <toolitem action="ActionsBold"/>
+    <toolitem action="ActionsItalics"/>
+    <placeholder name="FontAttributes">
+    </placeholder>
+    <toolitem action="ActionsBulletedList"/>
   </toolbar>
 
 </ui>
index 5d17534..92247fa 100644 (file)
 <ui>
 
   <menubar name="MenuBar">
+
+    <menu name="MessageMenu" action="Message">
+      <menuitem name="MessageReplyMenu" action="MessageReply"/>
+      <menuitem name="MessageReplyToAllMenu" action="MessageReplyToAll"/>
+      <menuitem name="MessageForwardMenu" action="MessageForward"/>
+      <menuitem name="MessageNewMenu"  action="MessageNew"/>
+      <menuitem name="MessageOpenMenu" action="MessageOpen"/>
+      <separator/>
+      <menuitem name="MessageDeleteMenu" action="MessageDelete"/>
+      <separator/>
+      <menuitem name="MessageDetailsMenu"      action="MessageDetails"/>
+    </menu>
        
     <menu name="EditMenu" action="Edit">
-      <menuitem name="EditUndoMenu" action="EditUndo"/>
-      <separator/>
       <menuitem name="EditCutMenu" action="EditCut"/>
       <menuitem name="EditCopyMenu" action="EditCopy"/>
       <menuitem name="EditPasteMenu" action="EditPaste"/>
index 97a76fa..c4d5b05 100644 (file)
@@ -223,11 +223,13 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self,
                                     TnyTransportAccount *transport_account,
                                     const gchar *from,  const gchar *to,
                                     const gchar *cc,  const gchar *bcc,
-                                    const gchar *subject, const gchar *body,
+                                    const gchar *subject, const gchar *plain_body,
+                                    const gchar *html_body,
                                     const GList *attachments_list)
 {
        TnyMsg *new_msg;
        ModestMailOperationPrivate *priv = NULL;
+       GList *node = NULL;
 
        g_return_if_fail (MODEST_IS_MAIL_OPERATION (self));
        g_return_if_fail (TNY_IS_TRANSPORT_ACCOUNT (transport_account));
@@ -242,7 +244,11 @@ modest_mail_operation_send_new_mail (ModestMailOperation *self,
                return;
        }
 
-       new_msg = modest_tny_msg_new (to, from, cc, bcc, subject, body, NULL); /* FIXME: attachments */
+       if (html_body == NULL) {
+               new_msg = modest_tny_msg_new (to, from, cc, bcc, subject, plain_body, (GSList *) attachments_list); /* FIXME: attachments */
+       } else {
+               new_msg = modest_tny_msg_new_html_plain (to, from, cc, bcc, subject, html_body, plain_body, (GSList *) attachments_list);
+       }
        if (!new_msg) {
                g_printerr ("modest: failed to create a new msg\n");
                return;
index c3ec8d2..c5f49fb 100644 (file)
@@ -104,7 +104,9 @@ void    modest_mail_operation_send_mail       (ModestMailOperation *self,
  * @cc: a comma-separated list of email addresses where to send a carbon copy
  * @bcc: a comma-separated list of email addresses where to send a blind carbon copy
  * @subject: the subject of the new mail
- * @body: the body of the new mail
+ * @plain_body: the plain text body of the new mail.
+ * @html_body: the html version of the body of the new mail. If NULL, the mail will
+ *             be sent with the plain body only.
  * @attachments_list: a #GList of attachments, each attachment must be a #TnyMimePart
  * 
  * Sends a new mail message using the provided
@@ -119,7 +121,8 @@ void    modest_mail_operation_send_new_mail   (ModestMailOperation *self,
                                               const gchar *cc,
                                               const gchar *bcc,
                                               const gchar *subject,
-                                              const gchar *body,
+                                              const gchar *plain_body,
+                                              const gchar *html_body,
                                               const GList *attachments_list);
 
 /**
index 6dd6a61..dc211c7 100644 (file)
@@ -280,7 +280,7 @@ send_mail (const gchar* account_name,
        mail_operation = modest_mail_operation_new ();
        modest_mail_operation_send_new_mail (mail_operation, account,
                                             from_string, mailto,
-                                            cc, bcc, subject, body,
+                                            cc, bcc, subject, body, NULL,
                                             NULL);
        if (modest_mail_operation_get_status (mail_operation) == 
            MODEST_MAIL_OPERATION_STATUS_FAILED) {
index 499a8c6..ea1710b 100644 (file)
@@ -570,6 +570,7 @@ init_stock_icons (void)
 /*                     MODEST_TOOLBAR_ICON_NEXT, */
 /*                     MODEST_TOOLBAR_ICON_PREV, */
 /*                     MODEST_TOOLBAR_ICON_STOP */
+                       MODEST_TOOLBAR_ICON_FORMAT_BULLETS,
                };
 
                registered = TRUE;
index 6a4f827..d168d40 100644 (file)
@@ -46,6 +46,7 @@
 
 static TnyMimePart * add_body_part (TnyMsg *msg, const gchar *body,
                                    const gchar *content_type, gboolean has_attachments);
+static TnyMimePart * add_html_body_part (TnyMsg *msg, const gchar *body);
 static void add_attachments (TnyMsg *msg, GList *attachments_list);
 static char * get_content_type(const gchar *s);
 static gboolean is_ascii(const gchar *s);
@@ -76,6 +77,43 @@ modest_tny_msg_new (const gchar* mailto, const gchar* from, const gchar *cc,
                
        /* Add the body of the new mail */      
        add_body_part (new_msg, body, content_type, (attachments ? TRUE: FALSE));
+       g_free (content_type);
+                      
+       /* Add attachments */
+       add_attachments (new_msg, (GList*) attachments);
+
+       return new_msg;
+}
+
+TnyMsg*
+modest_tny_msg_new_html_plain (const gchar* mailto, const gchar* from, const gchar *cc,
+                              const gchar *bcc, const gchar* subject, 
+                              const gchar *html_body, const gchar *plain_body,
+                              GSList *attachments)
+{
+       TnyPlatformFactory *fact;
+       TnyMsg *new_msg;
+       TnyHeader *header;
+       gchar *content_type;
+       
+       /* Create new msg */
+       fact    = modest_runtime_get_platform_factory ();
+       new_msg = tny_platform_factory_new_msg (fact);
+       header  = tny_msg_get_header (new_msg);
+       
+       tny_header_set_from (TNY_HEADER (header), from);
+       tny_header_set_replyto (TNY_HEADER (header), from);
+       tny_header_set_to (TNY_HEADER (header), mailto);
+       tny_header_set_cc (TNY_HEADER (header), cc);
+       tny_header_set_bcc (TNY_HEADER (header), bcc);
+       tny_header_set_subject (TNY_HEADER (header), subject);
+
+       content_type = get_content_type(plain_body);
+               
+       /* Add the body of the new mail */      
+       add_html_body_part (new_msg, html_body);
+       add_body_part (new_msg, plain_body, content_type, TRUE);
+       g_free (content_type);
                       
        /* Add attachments */
        add_attachments (new_msg, (GList*) attachments);
@@ -125,6 +163,39 @@ add_body_part (TnyMsg *msg,
        return text_body_part;
 }
 
+static TnyMimePart *
+add_html_body_part (TnyMsg *msg, 
+                   const gchar *body)
+{
+       TnyMimePart *html_body_part = NULL;
+       TnyStream *html_body_stream;
+
+       /* Create the stream */
+       html_body_stream = TNY_STREAM (tny_camel_stream_new
+                                      (camel_stream_mem_new_with_buffer
+                                       (body, strlen(body))));
+
+       /* Create body part if needed */
+       html_body_part = tny_platform_factory_new_mime_part
+               (modest_runtime_get_platform_factory ());
+
+       /* Construct MIME part */
+       tny_stream_reset (html_body_stream);
+       tny_mime_part_construct_from_stream (html_body_part,
+                                            html_body_stream,
+                                            "text/html; charset=utf-8");
+       tny_stream_reset (html_body_stream);
+
+       /* Add part if needed */
+       tny_mime_part_add_part (TNY_MIME_PART (msg), html_body_part);
+       g_object_unref (G_OBJECT(html_body_part));
+
+       /* Clean */
+       g_object_unref (html_body_stream);
+
+       return html_body_part;
+}
+
 static void
 add_attachments (TnyMsg *msg, GList *attachments_list)
 {
@@ -132,6 +203,7 @@ add_attachments (TnyMsg *msg, GList *attachments_list)
        TnyMimePart *attachment_part, *old_attachment;
        const gchar *attachment_content_type;
        const gchar *attachment_filename;
+       const gchar *attachment_cid;
        TnyStream *attachment_stream;
 
        for (pos = (GList *)attachments_list; pos; pos = pos->next) {
@@ -143,6 +215,7 @@ add_attachments (TnyMsg *msg, GList *attachments_list)
                        modest_runtime_get_platform_factory());
                
                attachment_content_type = tny_mime_part_get_content_type (old_attachment);
+               attachment_cid = tny_mime_part_get_content_id (old_attachment);
                                 
                tny_mime_part_construct_from_stream (attachment_part,
                                                     attachment_stream,
@@ -150,6 +223,7 @@ add_attachments (TnyMsg *msg, GList *attachments_list)
                tny_stream_reset (attachment_stream);
                
                tny_mime_part_set_filename (attachment_part, attachment_filename);
+               tny_mime_part_set_content_id (attachment_part, attachment_cid);
                
                tny_mime_part_add_part (TNY_MIME_PART (msg), attachment_part);
 /*             g_object_unref (attachment_part); */
index 250c6f8..d443a53 100644 (file)
@@ -80,6 +80,26 @@ TnyMsg* modest_tny_msg_new (const gchar* mailto, const gchar* mailfrom, const gc
                            GSList *attachments);
 
 /**
+ * modest_tny_msg_new_html_plain:
+ * @mailto: recipient for the message
+ * @mailfrom: sender of this message
+ * @cc: Cc: address for the message
+ * @bcc: Bcc: address for the message
+ * @subject: subject for the message
+ * @html_body: body for the message in HTML
+ * @plain_body: body for the message in plain text
+ * @attachments: a list of attachments (local URIs)
+ * 
+ * create a new TnyMsg with the given parameters
+ * 
+ * Returns: a new TnyMsg (free with g_object_unref)
+ */     
+TnyMsg* modest_tny_msg_new_html_plain (const gchar* mailto, const gchar* mailfrom, const gchar *cc,
+                                      const gchar *bcc, const gchar* subject, 
+                                      const gchar *html_body, const gchar *plain_body,
+                                      GSList *attachments);
+
+/**
  * modest_tny_msg_find_body_part:
  * @self: a message
  * @want_html: prefer HTML-part when there are multiple body parts?
index 032a094..7aec591 100644 (file)
@@ -960,7 +960,7 @@ modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link
 }
 
 void
-modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, int index,
+modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
                                             ModestWindow *win)
 {
        g_message (__FUNCTION__);
@@ -1021,8 +1021,9 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
                                             data->cc, 
                                             data->bcc,
                                             data->subject, 
-                                            data->body, 
-                                            NULL);
+                                            data->plain_body, 
+                                            data->html_body,
+                                            data->attachments);
        /* Frees */
        g_free (from);
        g_free (account_name);
@@ -1036,6 +1037,131 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
        gtk_widget_destroy (GTK_WIDGET (edit_window));
 }
 
+void 
+modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
+                                 ModestMsgEditWindow *window)
+{
+       ModestMsgEditFormatState *format_state = NULL;
+
+       g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
+       g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
+
+       if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
+               return;
+
+       format_state = modest_msg_edit_window_get_format_state (window);
+       g_return_if_fail (format_state != NULL);
+
+       format_state->bold = gtk_toggle_action_get_active (action);
+       modest_msg_edit_window_set_format_state (window, format_state);
+       g_free (format_state);
+       
+}
+
+void 
+modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
+                                    ModestMsgEditWindow *window)
+{
+       ModestMsgEditFormatState *format_state = NULL;
+
+       g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
+       g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
+
+       if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
+               return;
+
+       format_state = modest_msg_edit_window_get_format_state (window);
+       g_return_if_fail (format_state != NULL);
+
+       format_state->italics = gtk_toggle_action_get_active (action);
+       modest_msg_edit_window_set_format_state (window, format_state);
+       g_free (format_state);
+       
+}
+
+void 
+modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
+                                    ModestMsgEditWindow *window)
+{
+       ModestMsgEditFormatState *format_state = NULL;
+
+       g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
+       g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
+
+       if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
+               return;
+
+       format_state = modest_msg_edit_window_get_format_state (window);
+       g_return_if_fail (format_state != NULL);
+
+       format_state->bullet = gtk_toggle_action_get_active (action);
+       modest_msg_edit_window_set_format_state (window, format_state);
+       g_free (format_state);
+       
+}
+
+void 
+modest_ui_actions_on_change_justify (GtkRadioAction *action,
+                                    GtkRadioAction *selected,
+                                    ModestMsgEditWindow *window)
+{
+       ModestMsgEditFormatState *format_state = NULL;
+       GtkJustification value;
+
+       g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
+
+       if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
+               return;
+
+       value = gtk_radio_action_get_current_value (selected);
+
+       format_state = modest_msg_edit_window_get_format_state (window);
+       g_return_if_fail (format_state != NULL);
+
+       format_state->justification = value;
+       modest_msg_edit_window_set_format_state (window, format_state);
+       g_free (format_state);
+}
+
+void 
+modest_ui_actions_on_select_editor_color (GtkAction *action,
+                                         ModestMsgEditWindow *window)
+{
+       g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
+       g_return_if_fail (GTK_IS_ACTION (action));
+
+       if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
+               return;
+
+       modest_msg_edit_window_select_color (window);
+}
+
+void 
+modest_ui_actions_on_select_editor_background_color (GtkAction *action,
+                                                    ModestMsgEditWindow *window)
+{
+       g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
+       g_return_if_fail (GTK_IS_ACTION (action));
+
+       if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
+               return;
+
+       modest_msg_edit_window_select_background_color (window);
+}
+
+void 
+modest_ui_actions_on_insert_image (GtkAction *action,
+                                  ModestMsgEditWindow *window)
+{
+       g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
+       g_return_if_fail (GTK_IS_ACTION (action));
+
+       if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
+               return;
+
+       modest_msg_edit_window_insert_image (window);
+}
+
 /*
  * Shows a dialog with an entry that asks for some text. The returned
  * value must be freed by the caller. The dialog window title will be
index 542b062..2add3e1 100644 (file)
@@ -95,7 +95,7 @@ void     modest_ui_actions_on_msg_link_hover           (ModestMsgView *msgview,
 void     modest_ui_actions_on_msg_link_clicked         (ModestMsgView *msgview, const gchar* link,
                                                        ModestWindow *win);
 
-void     modest_ui_actions_on_msg_attachment_clicked   (ModestMsgView *msgview, int index,
+void     modest_ui_actions_on_msg_attachment_clicked   (ModestMsgView *msgview, TnyMimePart *mime_part,
                                                        ModestWindow *win);
 
 void     modest_ui_actions_on_msg_recpt_activated   (ModestMsgView *msgview, const gchar *address,
@@ -104,6 +104,28 @@ void     modest_ui_actions_on_msg_recpt_activated   (ModestMsgView *msgview, con
 void     modest_ui_actions_on_send                     (GtkWidget *widget,
                                                        ModestMsgEditWindow *edit_window);
 
+void     modest_ui_actions_on_toggle_bold              (GtkToggleAction *action,
+                                                       ModestMsgEditWindow *window);
+
+void     modest_ui_actions_on_toggle_italics           (GtkToggleAction *action,
+                                                       ModestMsgEditWindow *window);
+
+void     modest_ui_actions_on_toggle_bullets           (GtkToggleAction *action,
+                                                       ModestMsgEditWindow *window);
+
+void     modest_ui_actions_on_change_justify      (GtkRadioAction *action,
+                                                  GtkRadioAction *selected,
+                                                  ModestMsgEditWindow *window);
+
+void     modest_ui_actions_on_select_editor_color      (GtkAction *action,
+                                                       ModestMsgEditWindow *window);
+
+void     modest_ui_actions_on_select_editor_background_color      (GtkAction *action,
+                                                                  ModestMsgEditWindow *window);
+
+void     modest_ui_actions_on_insert_image             (GtkAction *action,
+                                                       ModestMsgEditWindow *window);
+
 void    modest_ui_actions_on_send_receive              (GtkAction *action, ModestWindow *win);
 
 void     modest_ui_actions_on_new_folder               (GtkAction *action,
index 08d11d5..1a49d87 100644 (file)
@@ -20,6 +20,8 @@ libmodest_widgets_la_SOURCES=          \
        modest-account-view-window.h   \
        modest-account-view.c          \
        modest-account-view.h          \
+       modest-attachment-view.c       \
+       modest-attachment-view.h       \
        modest-attachments-view.c      \
        modest-attachments-view.h      \
        modest-combo-box.c             \
diff --git a/src/widgets/modest-attachment-view.c b/src/widgets/modest-attachment-view.c
new file mode 100644 (file)
index 0000000..29a8e7b
--- /dev/null
@@ -0,0 +1,496 @@
+/* Copyright (c) 2007, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+//#include <glib/gi18n-lib.h>
+
+#include <string.h>
+#include <modest-attachment-view.h>
+#include <modest-platform.h>
+
+static GObjectClass *parent_class = NULL;
+
+/* signals */
+enum {
+       ACTIVATE_SIGNAL,
+       LAST_SIGNAL
+};
+
+typedef struct _ModestAttachmentViewPriv ModestAttachmentViewPriv;
+
+struct _ModestAttachmentViewPriv
+{
+       TnyMimePart *mime_part;
+
+       GtkWidget *icon;
+       GtkWidget *filename_view;
+       GtkWidget *size_view;
+
+       guint get_size_idle_id;
+       TnyStream *get_size_stream;
+       guint size;
+
+       PangoLayout *layout_full_filename;
+
+       gboolean button_pressed;
+       gdouble pressed_x, pressed_y;
+};
+
+#define UNKNOWN_FILE_ICON "qgn_list_gene_unknown_file"
+#define GET_SIZE_BUFFER_SIZE 128
+
+#define MODEST_ATTACHMENT_VIEW_GET_PRIVATE(o)  \
+       (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_ATTACHMENT_VIEW, ModestAttachmentViewPriv))
+
+static guint signals[LAST_SIGNAL] = {0};
+
+/* TnyMimePartView functions */
+static TnyMimePart *modest_attachment_view_get_part (TnyMimePartView *self);
+static TnyMimePart *modest_attachment_view_get_part_default (TnyMimePartView *self);
+static void modest_attachment_view_set_part (TnyMimePartView *self, TnyMimePart *mime_part);
+static void modest_attachment_view_set_part_default (TnyMimePartView *self, TnyMimePart *mime_part);
+static void modest_attachment_view_clear (TnyMimePartView *self);
+static void modest_attachment_view_clear_default (TnyMimePartView *self);
+
+/* Gtk events */
+static gint button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
+static gint button_release_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
+static void size_allocate (GtkWidget *widget, GtkAllocation *allocation);
+
+/* GObject and GInterface management */
+static void modest_attachment_view_instance_init (GTypeInstance *instance, gpointer g_class);
+static void modest_attachment_view_finalize (GObject *object);
+static void modest_attachment_view_class_init (ModestAttachmentViewClass *klass);
+static void tny_mime_part_view_init (gpointer g, gpointer iface_data);
+
+
+
+static gboolean get_size_idle_func (gpointer data);
+static void update_filename_request (ModestAttachmentView *self);
+
+
+
+static TnyMimePart *
+modest_attachment_view_get_part (TnyMimePartView *self)
+{
+       return MODEST_ATTACHMENT_VIEW_GET_CLASS (self)->get_part_func (self);
+}
+
+static TnyMimePart *
+modest_attachment_view_get_part_default (TnyMimePartView *self)
+{
+       ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (self);
+
+       if (priv->mime_part)
+               return TNY_MIME_PART (g_object_ref (priv->mime_part));
+       else
+               return NULL;
+}
+
+static void
+update_filename_request (ModestAttachmentView *self)
+{
+       ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (self);
+       gint width, height;
+       
+       pango_layout_set_text (PANGO_LAYOUT (priv->layout_full_filename), 
+                              gtk_label_get_text (GTK_LABEL (priv->filename_view)), -1);
+
+       pango_layout_get_pixel_size (priv->layout_full_filename, &width, &height);
+
+}
+
+static void
+modest_attachment_view_set_part (TnyMimePartView *self, TnyMimePart *mime_part)
+{
+       MODEST_ATTACHMENT_VIEW_GET_CLASS (self)->set_part_func (self, mime_part);
+       return;
+}
+
+
+static gboolean
+get_size_idle_func (gpointer data)
+{
+       ModestAttachmentView *self = (ModestAttachmentView *) data;
+       ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (self);
+       gssize readed_size;
+       gchar read_buffer[GET_SIZE_BUFFER_SIZE];
+       gchar *size_string;
+
+       if (priv->get_size_stream == NULL) {
+               priv->get_size_stream = tny_mime_part_get_stream (priv->mime_part);
+       }
+
+       readed_size = tny_stream_read (priv->get_size_stream, read_buffer, GET_SIZE_BUFFER_SIZE);
+       priv->size += readed_size;
+
+       if (tny_stream_is_eos (priv->get_size_stream)) {
+               size_string = g_strdup_printf (" (%d kb)", priv->size / 1024);
+               gtk_label_set_text (GTK_LABEL (priv->size_view), size_string);
+               g_free (size_string);
+
+               g_object_unref (priv->get_size_stream);
+
+               gtk_widget_queue_resize (priv->size_view);
+               priv->get_size_stream = NULL;
+               priv->get_size_idle_id = 0;
+       }
+
+       return (priv->get_size_stream != NULL);
+       
+}
+
+static void
+modest_attachment_view_set_part_default (TnyMimePartView *self, TnyMimePart *mime_part)
+{
+       ModestAttachmentViewPriv *priv = NULL;
+       const gchar *filename;
+       gchar *file_icon_name;
+       
+       g_return_if_fail (TNY_IS_MIME_PART_VIEW (self));
+       g_return_if_fail (TNY_IS_MIME_PART (mime_part));
+       priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (self);
+
+       if (priv->mime_part != NULL) {
+               g_object_unref (priv->mime_part);
+       }
+
+       priv->mime_part = mime_part;
+
+       if (priv->get_size_idle_id != 0) {
+               g_source_remove (priv->get_size_idle_id);
+               priv->get_size_idle_id = 0;
+       }
+
+       if (priv->get_size_stream != NULL) {
+               g_object_unref (priv->get_size_stream);
+               priv->get_size_stream = NULL;
+       }
+
+       priv->size = 0;
+
+       filename = tny_mime_part_get_filename (mime_part);
+       file_icon_name = modest_platform_get_file_icon_name (filename, 
+                                                            tny_mime_part_get_content_type (mime_part), 
+                                                            NULL);
+
+       if (file_icon_name) {
+               gtk_image_set_from_icon_name (GTK_IMAGE (priv->icon), file_icon_name, GTK_ICON_SIZE_MENU);
+               g_free (file_icon_name);
+       } else {
+               gtk_image_set_from_icon_name (GTK_IMAGE (priv->icon), UNKNOWN_FILE_ICON, GTK_ICON_SIZE_MENU);
+       }
+
+       gtk_label_set_text (GTK_LABEL (priv->filename_view), filename);
+       update_filename_request (MODEST_ATTACHMENT_VIEW (self));
+
+       gtk_label_set_text (GTK_LABEL (priv->size_view), " ");
+
+       priv->get_size_idle_id = g_idle_add ((GSourceFunc) get_size_idle_func, (gpointer) self);
+
+       gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+static void
+modest_attachment_view_clear (TnyMimePartView *self)
+{
+       MODEST_ATTACHMENT_VIEW_GET_CLASS (self)->clear_func (self);
+       return;
+}
+
+static void
+modest_attachment_view_clear_default (TnyMimePartView *self)
+{
+       ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (self);
+
+       if (priv->mime_part != NULL) {
+               g_object_unref (priv->mime_part);
+               priv->mime_part = NULL;
+       }
+
+       if (priv->get_size_idle_id != 0) {
+               g_source_remove (priv->get_size_idle_id);
+               priv->get_size_idle_id = 0;
+       }
+
+       if (priv->get_size_stream != NULL) {
+               g_object_unref (priv->get_size_stream);
+               priv->get_size_stream = NULL;
+       }
+
+       priv->size = 0;
+
+       gtk_image_set_from_icon_name (GTK_IMAGE (priv->icon), 
+                                     UNKNOWN_FILE_ICON,
+                                     GTK_ICON_SIZE_MENU);
+       gtk_label_set_text (GTK_LABEL (priv->filename_view), "");
+       update_filename_request (MODEST_ATTACHMENT_VIEW(self));
+       gtk_label_set_text (GTK_LABEL (priv->size_view), " ");
+
+       gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+static gint
+button_press_event (GtkWidget *widget,
+                   GdkEventButton *event,
+                   gpointer user_data)
+{
+       ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (MODEST_ATTACHMENT_VIEW (user_data));
+
+       if (event->type == GDK_BUTTON_PRESS && event->button == 1) {
+               priv->button_pressed = TRUE;
+               priv->pressed_x = event->x;
+               priv->pressed_y = event->y;
+       }
+       return TRUE;
+}
+
+static gint
+button_release_event (GtkWidget *widget,
+                     GdkEventButton *event,
+                     gpointer user_data)
+{
+       ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (MODEST_ATTACHMENT_VIEW (user_data));
+
+       if (event->type != GDK_BUTTON_RELEASE)
+               return TRUE;
+
+       if ((priv->button_pressed) &&
+           (event->type == GDK_BUTTON_RELEASE) &&
+           (priv->pressed_x == event->x) &&
+           (priv->pressed_y == event->y)) {
+               priv->button_pressed = FALSE;
+               if (event->button == 1) {
+                       g_signal_emit (G_OBJECT (user_data), signals[ACTIVATE_SIGNAL], 0);
+                       return TRUE;
+               }
+       }
+       priv->button_pressed = FALSE;
+       return TRUE;
+}
+
+
+
+/**
+ * modest_attachment_view_new:
+ * @mime_part: a #TnyMimePart
+ *
+ * Constructor for attachment view widget.
+ *
+ * Return value: a new #ModestAttachmentView instance implemented for Gtk+
+ **/
+GtkWidget*
+modest_attachment_view_new (TnyMimePart *mime_part)
+{
+       ModestAttachmentView *self = g_object_new (MODEST_TYPE_ATTACHMENT_VIEW, 
+                                                  "homogeneous", FALSE,
+                                                  "spacing", 0,
+                                                  NULL);
+
+       modest_attachment_view_set_part (TNY_MIME_PART_VIEW (self), mime_part);
+
+       return GTK_WIDGET (self);
+}
+
+static void
+modest_attachment_view_instance_init (GTypeInstance *instance, gpointer g_class)
+{
+       ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (instance);
+       PangoContext *context;
+       GtkWidget *icon_eventbox;
+
+       priv->mime_part = NULL;
+       priv->icon = gtk_image_new ();
+       priv->filename_view = gtk_label_new ("");
+       gtk_label_set_line_wrap (GTK_LABEL (priv->filename_view), FALSE);
+       gtk_label_set_ellipsize (GTK_LABEL (priv->filename_view), PANGO_ELLIPSIZE_END);
+       gtk_label_set_single_line_mode (GTK_LABEL (priv->filename_view), TRUE);
+       gtk_label_set_selectable (GTK_LABEL (priv->filename_view), TRUE);
+       priv->size_view = gtk_label_new (" ");
+       gtk_label_set_line_wrap (GTK_LABEL (priv->size_view), FALSE);
+       gtk_label_set_selectable (GTK_LABEL (priv->size_view), TRUE);
+       gtk_misc_set_alignment (GTK_MISC (priv->size_view), 0.0, 0.5);
+       gtk_misc_set_alignment (GTK_MISC (priv->filename_view), 0.0, 0.5);
+
+       priv->get_size_idle_id = 0;
+       priv->get_size_stream = NULL;
+       priv->size = 0;
+
+       icon_eventbox = gtk_event_box_new ();
+
+       gtk_container_add (GTK_CONTAINER (icon_eventbox), priv->icon);
+       gtk_box_pack_start (GTK_BOX (instance), icon_eventbox, FALSE, FALSE, 0);
+       gtk_box_pack_start (GTK_BOX (instance), priv->filename_view, TRUE, TRUE, 0);
+       gtk_box_pack_start (GTK_BOX (instance), priv->size_view, FALSE, FALSE, 0);
+
+       context = gtk_widget_get_pango_context (priv->filename_view);
+       priv->layout_full_filename = pango_layout_new (context);
+
+       g_signal_connect (G_OBJECT (priv->filename_view), "button-press-event", G_CALLBACK (button_press_event), instance);
+       g_signal_connect (G_OBJECT (priv->filename_view), "button-release-event", G_CALLBACK (button_release_event), instance);
+               g_signal_connect (G_OBJECT (priv->size_view), "button-press-event", G_CALLBACK (button_press_event), instance);
+       g_signal_connect (G_OBJECT (priv->size_view), "button-release-event", G_CALLBACK (button_release_event), instance);
+       g_signal_connect (G_OBJECT (icon_eventbox), "button-press-event", G_CALLBACK (button_press_event), instance);
+       g_signal_connect (G_OBJECT (icon_eventbox), "button-release-event", G_CALLBACK (button_release_event), instance);
+
+       return;
+}
+
+static void
+modest_attachment_view_finalize (GObject *object)
+{
+       ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (object);
+
+       if (priv->get_size_idle_id) {
+               g_source_remove (priv->get_size_idle_id);
+               priv->get_size_idle_id = 0;
+       }
+
+       if (priv->get_size_stream != NULL) {
+               g_object_unref (priv->get_size_stream);
+               priv->get_size_stream = NULL;
+       }
+
+       if (G_LIKELY (priv->mime_part)) {
+               g_object_unref (G_OBJECT (priv->mime_part));
+               priv->mime_part = NULL;
+       }
+
+       (*parent_class->finalize) (object);
+
+       return;
+}
+
+static void
+size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+       ModestAttachmentViewPriv *priv = MODEST_ATTACHMENT_VIEW_GET_PRIVATE (widget);
+       gint width, width_diff;
+
+       GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
+       pango_layout_get_pixel_size (priv->layout_full_filename, &width, NULL);
+       width_diff = priv->filename_view->allocation.width - width;
+       if (width_diff > 0) {
+               GtkAllocation filename_alloc, filesize_alloc;
+               filename_alloc = priv->filename_view->allocation;
+               filesize_alloc = priv->size_view->allocation;
+               filename_alloc.width -= width_diff;
+               filesize_alloc.width += width_diff;
+               filesize_alloc.x -= width_diff;
+               gtk_widget_size_allocate (priv->filename_view, &filename_alloc);
+               gtk_widget_size_allocate (priv->size_view, &filesize_alloc);
+       }
+       
+}
+
+
+static void 
+modest_attachment_view_class_init (ModestAttachmentViewClass *klass)
+{
+       GObjectClass *object_class;
+       GtkWidgetClass *widget_class;
+
+       parent_class = g_type_class_peek_parent (klass);
+       object_class = (GObjectClass*) klass;
+       widget_class = GTK_WIDGET_CLASS (klass);
+
+       object_class->finalize = modest_attachment_view_finalize;
+
+       klass->get_part_func = modest_attachment_view_get_part_default;
+       klass->set_part_func = modest_attachment_view_set_part_default;
+       klass->clear_func = modest_attachment_view_clear_default;
+       klass->activate = NULL;
+
+       widget_class->size_allocate = size_allocate;
+
+       g_type_class_add_private (object_class, sizeof (ModestAttachmentViewPriv));
+
+       signals[ACTIVATE_SIGNAL] =
+               g_signal_new ("activate",
+                             G_TYPE_FROM_CLASS (object_class),
+                             G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+                             G_STRUCT_OFFSET(ModestAttachmentViewClass, activate),
+                             NULL, NULL,
+                             g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 0);
+       
+       return;
+}
+
+static void
+tny_mime_part_view_init (gpointer g, gpointer iface_data)
+{
+        TnyMimePartViewIface *klass = (TnyMimePartViewIface *)g;
+
+        klass->get_part_func = modest_attachment_view_get_part;
+        klass->set_part_func = modest_attachment_view_set_part;
+        klass->clear_func = modest_attachment_view_clear;
+
+        return;
+}
+
+GType 
+modest_attachment_view_get_type (void)
+{
+       static GType type = 0;
+
+       if (G_UNLIKELY(type == 0))
+       {
+               static const GTypeInfo info = 
+               {
+                 sizeof (ModestAttachmentViewClass),
+                 NULL,   /* base_init */
+                 NULL,   /* base_finalize */
+                 (GClassInitFunc) modest_attachment_view_class_init,   /* class_init */
+                 NULL,   /* class_finalize */
+                 NULL,   /* class_data */
+                 sizeof (ModestAttachmentView),
+                 0,      /* n_preallocs */
+                 modest_attachment_view_instance_init    /* instance_init */
+               };
+
+               static const GInterfaceInfo tny_mime_part_view_info =
+               {
+                       (GInterfaceInitFunc) tny_mime_part_view_init, /* interface_init */
+                       NULL,        /* interface_finalize */
+                       NULL         /* interface_data */
+               };
+
+               type = g_type_register_static (GTK_TYPE_HBOX,
+                       "ModestAttachmentView",
+                       &info, 0);
+
+               g_type_add_interface_static (type, TNY_TYPE_MIME_PART_VIEW,
+                                            &tny_mime_part_view_info);
+
+       }
+
+       return type;
+}
diff --git a/src/widgets/modest-attachment-view.h b/src/widgets/modest-attachment-view.h
new file mode 100644 (file)
index 0000000..fe6416e
--- /dev/null
@@ -0,0 +1,73 @@
+/* Copyright (c) 2007, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MODEST_ATTACHMENT_VIEW_H
+#define MODEST_ATTACHMENT_VIEW_H
+#include <gtk/gtk.h>
+#include <glib-object.h>
+#include <tny-mime-part-view.h>
+
+G_BEGIN_DECLS
+
+#define MODEST_TYPE_ATTACHMENT_VIEW             (modest_attachment_view_get_type ())
+#define MODEST_ATTACHMENT_VIEW(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), MODEST_TYPE_ATTACHMENT_VIEW, ModestAttachmentView))
+#define MODEST_ATTACHMENT_VIEW_CLASS(vtable)    (G_TYPE_CHECK_CLASS_CAST ((vtable), MODEST_TYPE_ATTACHMENT_VIEW, ModestAttachmentViewClass))
+#define MODEST_IS_ATTACHMENT_VIEW(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MODEST_TYPE_ATTACHMENT_VIEW))
+#define MODEST_IS_ATTACHMENT_VIEW_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), MODEST_TYPE_ATTACHMENT_VIEW))
+#define MODEST_ATTACHMENT_VIEW_GET_CLASS(inst)  (G_TYPE_INSTANCE_GET_CLASS ((inst), MODEST_TYPE_ATTACHMENT_VIEW, ModestAttachmentViewClass))
+
+typedef struct _ModestAttachmentView ModestAttachmentView;
+typedef struct _ModestAttachmentViewClass ModestAttachmentViewClass;
+
+struct _ModestAttachmentView
+{
+       GtkHBox parent;
+
+};
+
+struct _ModestAttachmentViewClass
+{
+       GtkHBoxClass parent_class;
+
+       /* virtual methods */
+       TnyMimePart* (*get_part_func) (TnyMimePartView *self);
+       void (*set_part_func) (TnyMimePartView *self, TnyMimePart *part);
+       void (*clear_func) (TnyMimePartView *self);
+
+       /* signals */
+       void (*activate)           (ModestAttachmentView *attachment_view);
+};
+
+GType modest_attachment_view_get_type (void);
+
+GtkWidget* modest_attachment_view_new (TnyMimePart *mime_part);
+
+G_END_DECLS
+
+#endif
index 8be4f73..d07635e 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <modest-platform.h>
 #include <modest-runtime.h>
+#include <modest-attachment-view.h>
 #include <modest-attachments-view.h>
 
 static GObjectClass *parent_class = NULL;
@@ -61,6 +62,16 @@ struct _ModestAttachmentsViewPriv
 
 static guint signals[LAST_SIGNAL] = {0};
 
+static void
+activate_attachment (ModestAttachmentView *attachment_view,
+                    gpointer userdata)
+{
+       TnyMimePart *mime_part;
+      
+       mime_part = tny_mime_part_view_get_part (TNY_MIME_PART_VIEW (attachment_view));
+       g_signal_emit (G_OBJECT (userdata), signals[ACTIVATE_SIGNAL], 0, mime_part);
+       g_object_unref (mime_part);
+}
 
 /**
  * modest_attachments_view_new:
@@ -73,7 +84,11 @@ static guint signals[LAST_SIGNAL] = {0};
 GtkWidget*
 modest_attachments_view_new (TnyMsg *msg)
 {
-       ModestAttachmentsView *self = g_object_new (MODEST_TYPE_ATTACHMENTS_VIEW, NULL);
+       ModestAttachmentsView *self = g_object_new (MODEST_TYPE_ATTACHMENTS_VIEW, 
+                                                   "homogeneous", FALSE,
+                                                   "spacing", 0,
+                                                   "resize-mode", GTK_RESIZE_PARENT,
+                                                   NULL);
 
        modest_attachments_view_set_message (self, msg);
 
@@ -86,11 +101,7 @@ modest_attachments_view_set_message (ModestAttachmentsView *attachments_view, Tn
        ModestAttachmentsViewPriv *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (attachments_view);
        TnyList *parts;
        TnyIterator *iter;
-       gint index = 0;
-       GtkTextBuffer *buffer = NULL;
        gboolean has_first = FALSE;
-       GtkTextIter text_iter;
-       gint icon_height;
 
        if (priv->msg) 
                g_object_unref (priv->msg);
@@ -98,13 +109,10 @@ modest_attachments_view_set_message (ModestAttachmentsView *attachments_view, Tn
                g_object_ref (G_OBJECT(msg));
        
        priv->msg = msg;
-       
-       buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (attachments_view));
-       gtk_text_buffer_set_text (buffer, "", -1);
-       gtk_text_buffer_get_end_iter (buffer, &text_iter);
 
+       gtk_container_foreach (GTK_CONTAINER (attachments_view), (GtkCallback) gtk_widget_destroy, NULL);
+       
        if (priv->msg == NULL) {
-               gtk_widget_hide (GTK_WIDGET (attachments_view));
                return;
        }
 
@@ -112,121 +120,30 @@ modest_attachments_view_set_message (ModestAttachmentsView *attachments_view, Tn
        tny_mime_part_get_parts (TNY_MIME_PART (priv->msg), parts);
        iter = tny_list_create_iterator (parts);
 
-       gtk_icon_size_lookup (GTK_ICON_SIZE_BUTTON, NULL, &icon_height);
-
        while (!tny_iterator_is_done (iter)) {
                TnyMimePart *part;
 
-               ++index;
                part = TNY_MIME_PART (tny_iterator_get_current (iter));
                if (tny_mime_part_is_attachment (part)) {
-                       const gchar *filename = tny_mime_part_get_filename (part);
-                       gchar *file_icon_name = 
-                               modest_platform_get_file_icon_name (filename, tny_mime_part_get_content_type(part) , NULL);
-                       GdkPixbuf *pixbuf = NULL;
-                       GtkTextTag *tag = NULL;
-
-                       if (has_first) {
-                               gtk_text_buffer_insert (buffer, &text_iter, ", ", -1);
-                               gtk_text_buffer_get_end_iter (buffer, &text_iter);
-                       }
-                       
-                       tag = gtk_text_buffer_create_tag (buffer, NULL,
-                                                         "underline", PANGO_UNDERLINE_SINGLE,
-                                                         "foreground", "blue",
-                                                         NULL);
-                       
-                       g_object_set_data (G_OBJECT (tag), "attachment-index", GINT_TO_POINTER (index));
-                       g_object_set_data (G_OBJECT (tag), "attachment-set", GINT_TO_POINTER (TRUE));
-                       
-                       if (file_icon_name) {
-                               pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), file_icon_name, 
-                                                                  icon_height, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
-                               if (pixbuf) {
-                                       GtkTextTag *pixbuf_tag;
-                                       GtkTextIter iter2;
-                                       pixbuf_tag = gtk_text_buffer_create_tag (buffer, NULL, NULL);
-                                       g_object_set_data (G_OBJECT (pixbuf_tag), "attachment-index", GINT_TO_POINTER (index));
-                                       g_object_set_data (G_OBJECT (pixbuf_tag), "attachment-set", GINT_TO_POINTER (TRUE));
-                                       gtk_text_buffer_insert_pixbuf (buffer, &text_iter, pixbuf);
-                                       iter2 = text_iter;
-                                       gtk_text_iter_backward_char (&iter2);
-                                       gtk_text_buffer_apply_tag (buffer, pixbuf_tag, &iter2, &text_iter);
-                                       gtk_text_buffer_get_end_iter (buffer, &text_iter);
-                               }
-                       }
-                       gtk_text_buffer_insert_with_tags (buffer, &text_iter, filename, -1, tag, NULL);
-                       gtk_text_buffer_get_end_iter (buffer, &text_iter);
-                       if (file_icon_name)
-                               g_free (file_icon_name);
+                       GtkWidget *att_view = NULL;
+                       att_view = modest_attachment_view_new (part);
+                       gtk_box_pack_end (GTK_BOX (attachments_view), att_view, FALSE, FALSE, 0);
+                       gtk_widget_show_all (att_view);
+                       g_signal_connect (G_OBJECT (att_view), "activate", G_CALLBACK (activate_attachment), (gpointer) attachments_view);
                        has_first = TRUE;
                }
                g_object_unref (part);
                tny_iterator_next (iter);
        }
 
-       if (has_first)
-               gtk_widget_show (GTK_WIDGET (attachments_view));
-       else
-               gtk_widget_hide (GTK_WIDGET (attachments_view));
-
-}
-
-static gboolean
-button_release_event (GtkWidget *widget,
-                     GdkEventButton *event,
-                     gpointer user_data)
-{
-       gint buffer_x, buffer_y;
-       GtkTextIter iter;
-       GSList *tags = NULL;
-       GSList *node = NULL;
-       
-       if ((event->type != GDK_BUTTON_RELEASE) 
-           || (event->button != 1))
-               return FALSE;
-       
-       gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (widget), GTK_TEXT_WINDOW_WIDGET,
-                                              event->x, event->y, &buffer_x, &buffer_y);
-       gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (widget), &iter, buffer_x, buffer_y);
-
-       tags = gtk_text_iter_get_tags (&iter);
-
-       for (node = tags; node != NULL; node = g_slist_next (node)) {
-               GtkTextTag *tag = node->data;
-               gboolean is_attachment = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "attachment-set"));
-
-               if (is_attachment) {
-                       gint attachment_index = 0;
+       gtk_widget_queue_draw (GTK_WIDGET (attachments_view));
 
-                       attachment_index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tag), "attachment-index"));
-                       g_signal_emit (G_OBJECT (widget), signals[ACTIVATE_SIGNAL], 0,
-                                      attachment_index);
-                       break;
-               }
-               
-       }
-       return FALSE;
 }
 
 static void
 modest_attachments_view_instance_init (GTypeInstance *instance, gpointer g_class)
 {
        ModestAttachmentsViewPriv *priv = MODEST_ATTACHMENTS_VIEW_GET_PRIVATE (instance);
-       GtkTextBuffer *buffer = NULL;
-
-       gtk_text_view_set_editable (GTK_TEXT_VIEW (instance), FALSE);
-       gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (instance), GTK_WRAP_WORD_CHAR);
-       gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (instance), 0);
-       gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (instance), 0);
-       gtk_text_view_set_justification (GTK_TEXT_VIEW (instance), GTK_JUSTIFY_LEFT);
-       gtk_text_view_set_left_margin (GTK_TEXT_VIEW (instance), 0);
-       gtk_text_view_set_right_margin (GTK_TEXT_VIEW (instance), 0);
-       gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (instance), FALSE);
-
-       buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (instance));
-
-       g_signal_connect (G_OBJECT (instance), "button-release-event", G_CALLBACK (button_release_event), NULL);
 
        priv->msg = NULL;
 
@@ -270,8 +187,8 @@ modest_attachments_view_class_init (ModestAttachmentsViewClass *klass)
                              G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
                              G_STRUCT_OFFSET(ModestAttachmentsViewClass, activate),
                              NULL, NULL,
-                             g_cclosure_marshal_VOID__INT,
-                             G_TYPE_NONE, 1, G_TYPE_INT);
+                             g_cclosure_marshal_VOID__OBJECT,
+                             G_TYPE_NONE, 1, G_TYPE_OBJECT);
        
        return;
 }
@@ -296,7 +213,7 @@ modest_attachments_view_get_type (void)
                  modest_attachments_view_instance_init    /* instance_init */
                };
 
-               type = g_type_register_static (GTK_TYPE_TEXT_VIEW,
+               type = g_type_register_static (GTK_TYPE_VBOX,
                        "ModestAttachmentsView",
                        &info, 0);
 
index fe11722..c4472e1 100644 (file)
@@ -47,15 +47,15 @@ typedef struct _ModestAttachmentsViewClass ModestAttachmentsViewClass;
 
 struct _ModestAttachmentsView
 {
-       GtkTextView parent;
+       GtkVBox parent;
 
 };
 
 struct _ModestAttachmentsViewClass
 {
-       GtkTextViewClass parent_class;
+       GtkVBoxClass parent_class;
 
-       void (*activate)           (ModestAttachmentsView *attachments_view, gint index);
+       void (*activate)           (ModestAttachmentsView *attachments_view, TnyMimePart *mime_part);
 };
 
 GType modest_attachments_view_get_type (void);
index 54720fd..93d0e2c 100644 (file)
@@ -65,6 +65,56 @@ struct _ModestMailHeaderViewPriv
 static guint signals[LAST_SIGNAL] = {0};
 
 static void
+add_date_time_header (ModestMailHeaderView *mail_header, const gchar *name, time_t date)
+{
+       const guint BUF_SIZE = 64; 
+       gchar date_buf [BUF_SIZE];
+       gchar time_buf [BUF_SIZE];
+
+       ModestMailHeaderViewPriv *priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (mail_header);
+       GtkWidget *hbox, *date_hbox, *time_hbox;
+       GtkWidget *label;
+       gchar *bolded_field = NULL;
+
+       modest_text_utils_strftime (date_buf, BUF_SIZE, "%x", date);
+       modest_text_utils_strftime (time_buf, BUF_SIZE, "%X", date);
+
+       hbox = gtk_hbox_new (FALSE, 48);
+       date_hbox = gtk_hbox_new (FALSE, 12);
+       time_hbox = gtk_hbox_new (FALSE, 12);
+
+       label = gtk_label_new (NULL);
+       bolded_field = g_strconcat ("<b>", name, "</b>", NULL);
+       gtk_label_set_markup (GTK_LABEL (label), bolded_field);
+       g_free (bolded_field);
+       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+       gtk_box_pack_start (GTK_BOX (date_hbox), label, FALSE, FALSE, 0);
+       gtk_size_group_add_widget (priv->labels_size_group, label);
+
+       label = gtk_label_new(date_buf);
+       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+       gtk_box_pack_start (GTK_BOX (date_hbox), label, TRUE, TRUE, 0);
+
+       gtk_box_pack_start (GTK_BOX (hbox), date_hbox, FALSE, FALSE, 0);
+
+       label = gtk_label_new(NULL);
+       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+       bolded_field = g_strconcat ("<b>", _("mail_va_time"), "</b>", NULL);
+       gtk_label_set_markup (GTK_LABEL (label), bolded_field);
+       g_free (bolded_field);
+       gtk_box_pack_start (GTK_BOX (time_hbox), label, FALSE, FALSE, 0);
+
+       label = gtk_label_new(time_buf);
+       gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+       gtk_box_pack_start (GTK_BOX (time_hbox), label, TRUE, TRUE, 0);
+
+       gtk_box_pack_start (GTK_BOX (hbox), time_hbox, TRUE, TRUE, 0);
+
+       gtk_box_pack_start (GTK_BOX (priv->headers_vbox), hbox, FALSE, FALSE, 0);
+       gtk_widget_show (hbox);
+}
+
+static void
 activate_recpt (GtkWidget *recpt_view, const gchar *address, gpointer user_data)
 {
        ModestMailHeaderView * view = MODEST_MAIL_HEADER_VIEW (user_data);
@@ -203,6 +253,7 @@ modest_mail_header_view_set_header_default (TnyHeaderView *self, TnyHeader *head
        if (header && G_IS_OBJECT (header))
        {
                const gchar *to, *from, *subject, *bcc, *cc;
+               GtkWidget *subject_box, *subject_label;
 
                g_object_ref (G_OBJECT (header)); 
                priv->header = header;
@@ -216,34 +267,55 @@ modest_mail_header_view_set_header_default (TnyHeaderView *self, TnyHeader *head
                cc = tny_header_get_cc (header);
                bcc = tny_header_get_bcc (header);
 
+               subject_box = gtk_hbox_new (FALSE, 12);
+               subject_label = gtk_label_new (NULL);
                if (subject)
-                       add_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_subject"), subject);
+                       gtk_label_set_text (GTK_LABEL (subject_label), subject);
+               else
+                       gtk_label_set_text (GTK_LABEL (subject_label), _("mail_va_no_subject"));
+               gtk_label_set_single_line_mode (GTK_LABEL (subject_label), TRUE);
+               gtk_label_set_ellipsize (GTK_LABEL (subject_label), PANGO_ELLIPSIZE_END);
+               gtk_label_set_selectable (GTK_LABEL (subject_label), TRUE);
+               gtk_misc_set_alignment (GTK_MISC (subject_label), 0.0, 0.0);
+
+               /* TODO: code disabled until we can get real priority information from message */
+/*             if (tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY) { */
+/*                     GtkWidget *priority_icon = gtk_image_new_from_icon_name ("qgn_list_messaging_high", GTK_ICON_SIZE_MENU); */
+/*                     gtk_box_pack_start (GTK_BOX (subject_box), priority_icon, FALSE, FALSE, 0); */
+/*             } */
+               gtk_box_pack_start (GTK_BOX (subject_box), subject_label, TRUE, TRUE, 0);
                if (priv->is_outgoing) {
-                       gchar *sent = modest_text_utils_get_display_date (tny_header_get_date_sent (header));
                        gchar *bolded_label = g_strconcat ("<b>", _("mail_va_to"), "</b>", NULL);
                        gtk_label_set_markup (GTK_LABEL (priv->fromto_label), bolded_label);
                        g_free (bolded_label);
                        if (to)
                                modest_recpt_view_set_recipients (MODEST_RECPT_VIEW (priv->fromto_contents), to);
+                       if (cc)
+                               add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_cc"), cc);
+                       if (bcc)
+                               add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_hotfix1"), bcc);
+                       if (priv->is_draft&& from)
+                               add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_from"), from);
+                       modest_mail_header_view_add_custom_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_subject"), subject_box, TRUE, TRUE);
                        if (priv->is_draft)
-                               add_header (MODEST_MAIL_HEADER_VIEW (self), _("fixme_Last saved:"), sent);
+                               add_date_time_header (MODEST_MAIL_HEADER_VIEW (self), _("fixme_Last saved:"), tny_header_get_date_sent (header));
                        else
-                               add_header (MODEST_MAIL_HEADER_VIEW (self), _("fixme_Sent:"), sent);
-                       g_free (sent);
+                               add_date_time_header (MODEST_MAIL_HEADER_VIEW (self), _("fixme_Sent:"), tny_header_get_date_sent (header));
                } else {
-                       gchar *received = modest_text_utils_get_display_date (tny_header_get_date_received (header));
                        gchar *bolded_label = g_strconcat ("<b>", _("mail_va_from"), "</b>", NULL);
                        gtk_label_set_markup (GTK_LABEL (priv->fromto_label), bolded_label);
                        g_free (bolded_label);
                        if (from)
                                modest_recpt_view_set_recipients (MODEST_RECPT_VIEW (priv->fromto_contents), from);
-                       add_header (MODEST_MAIL_HEADER_VIEW (self), _("fixme_Received:"), received);
-                       g_free (received);
+                       if (cc)
+                               add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_cc"), cc);
+                       if (bcc)
+                               add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_hotfix1"), bcc);
+                       if (to)
+                               add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_to"), to);
+                       modest_mail_header_view_add_custom_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_subject"), subject_box, TRUE, TRUE);
+                       add_date_time_header (MODEST_MAIL_HEADER_VIEW (self), _("fixme_Received:"), tny_header_get_date_received (header));
                }
-               if (cc)
-                       add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_cc"), cc);
-               if (bcc)
-                       add_recpt_header (MODEST_MAIL_HEADER_VIEW (self), _("mail_va_hotfix1"), bcc);
        }
 
        gtk_widget_show_all (GTK_WIDGET (self));
@@ -299,6 +371,46 @@ expander_activate (GtkWidget *expander, ModestMailHeaderView *header_view)
        gtk_widget_queue_draw (GTK_WIDGET (priv->expander));
 }
 
+const GtkWidget *
+modest_mail_header_view_add_custom_header (ModestMailHeaderView *header_view,
+                                          const gchar *label,
+                                          GtkWidget *custom_widget,
+                                          gboolean with_expander,
+                                          gboolean start)
+{
+       ModestMailHeaderViewPriv *priv;
+       g_return_val_if_fail (MODEST_IS_MAIL_HEADER_VIEW (header_view), NULL);
+       GtkWidget *hbox;
+       GtkWidget *label_field;
+       gchar *bolded_field = NULL;
+
+       priv = MODEST_MAIL_HEADER_VIEW_GET_PRIVATE (header_view);
+       hbox = gtk_hbox_new (FALSE, 12);
+       label_field = gtk_label_new (NULL);
+       if (label != NULL)
+               bolded_field = g_strconcat ("<b>", label, "</b>", NULL);
+       gtk_label_set_markup (GTK_LABEL (label_field), bolded_field);
+       g_free (bolded_field);
+       gtk_misc_set_alignment (GTK_MISC (label_field), 0.0, 0.0);
+       gtk_box_pack_start (GTK_BOX (hbox), label_field, FALSE, FALSE, 0);
+       gtk_box_pack_start (GTK_BOX (hbox), custom_widget, TRUE, TRUE, 0);
+       gtk_size_group_add_widget (priv->labels_size_group, label_field);
+
+       if (with_expander) {
+               if (start)
+                       gtk_box_pack_start (GTK_BOX (priv->headers_vbox), hbox, FALSE, FALSE, 0);
+               else
+                       gtk_box_pack_end (GTK_BOX (priv->headers_vbox), hbox, FALSE, FALSE, 0);
+       } else {
+               if (start)
+                       gtk_box_pack_start (GTK_BOX (priv->main_vbox), hbox, FALSE, FALSE, 0);
+               else
+                       gtk_box_pack_end (GTK_BOX (priv->main_vbox), hbox, FALSE, FALSE, 0);
+       }
+
+       return hbox;
+}
+
 /**
  * modest_mail_header_view_new:
  *
index bf76528..ff2a3a5 100644 (file)
@@ -69,6 +69,12 @@ struct _ModestMailHeaderViewClass
 GType modest_mail_header_view_get_type (void);
 TnyHeaderView* modest_mail_header_view_new (void);
 
+const GtkWidget *modest_mail_header_view_add_custom_header (ModestMailHeaderView *header_view,
+                                                           const gchar *label,
+                                                           GtkWidget *custom_widget,
+                                                           gboolean with_expander,
+                                                           gboolean start);
+
 G_END_DECLS
 
 #endif
index 3a6ae4d..d10bcd0 100644 (file)
@@ -42,9 +42,14 @@ static const GtkActionEntry modest_msg_edit_action_entries [] = {
        { "View", NULL, N_("_View") },
        { "Insert", NULL, N_("_Insert") },
        { "Format", NULL, N_("For_mat") },
+       { "Alignment", NULL, N_("_Alignment") },
+       { "Attachments", NULL, N_("Attachments") },
 
        /* ACTIONS */
        { "ActionsSend", MODEST_STOCK_MAIL_SEND, N_("Send"),  NULL, N_("Send a message"),  G_CALLBACK (modest_ui_actions_on_send) },
+       { "ActionsFontColor", GTK_STOCK_SELECT_COLOR, N_("Color"), NULL, N_("Change text color"), G_CALLBACK (modest_ui_actions_on_select_editor_color)},
+       { "BackgroundColor", GTK_STOCK_SELECT_COLOR, N_("Background color"), NULL, N_("Change background color"), G_CALLBACK (modest_ui_actions_on_select_editor_background_color)},
+       { "InsertImage", NULL, N_("Insert image..."), NULL, N_("Insert image"), G_CALLBACK (modest_ui_actions_on_insert_image)},
 };
 
 static const GtkToggleActionEntry modest_msg_edit_toggle_action_entries [] = {
@@ -53,6 +58,17 @@ static const GtkToggleActionEntry modest_msg_edit_toggle_action_entries [] = {
        { "ViewToField",   NULL,    N_("To: field"),  NULL, N_("Shows the To: field"),  NULL, TRUE  },
        { "ViewCcField",   NULL,    N_("Cc: field"),  NULL, N_("Shows the Cc: field"),  NULL, TRUE  },
        { "ViewBccField",  NULL,    N_("Bcc: filed"), NULL, N_("Shows the Bcc: field"), NULL, FALSE },
+
+       /* Rich text editor functions */
+       { "ActionsBold", GTK_STOCK_BOLD, N_("Bold"), NULL, N_("Use bold"), G_CALLBACK (modest_ui_actions_on_toggle_bold), FALSE },
+       { "ActionsItalics", GTK_STOCK_ITALIC, N_("Italics"), NULL, N_("Use italics"), G_CALLBACK (modest_ui_actions_on_toggle_italics), FALSE },
+       { "ActionsBulletedList", MODEST_TOOLBAR_ICON_FORMAT_BULLETS, N_("Bullet list"), NULL, N_("Add a bullet list"), G_CALLBACK (modest_ui_actions_on_toggle_bullets), FALSE },
+};
+
+static const GtkRadioActionEntry modest_msg_edit_alignment_radio_action_entries [] = {
+       { "AlignmentLeft", NULL, N_("Left"), NULL, N_("Align to the left"), GTK_JUSTIFY_LEFT },
+       { "AlignmentCenter", NULL, N_("Center"), NULL, N_("Align to the center"), GTK_JUSTIFY_CENTER },
+       { "AlignmentRight", NULL, N_("Right"), NULL, N_("Align to the right"), GTK_JUSTIFY_RIGHT },
 };
 
 G_END_DECLS
index 575d493..4d91d4a 100644 (file)
@@ -65,10 +65,26 @@ typedef enum  {
        MODEST_EDIT_TYPE_NUM
 } ModestEditType;
 
+typedef enum {
+       MODEST_MSG_EDIT_FORMAT_TEXT,
+       MODEST_MSG_EDIT_FORMAT_HTML
+} ModestMsgEditFormat;
+
 typedef struct  {
-       gchar *from, *to, *cc, *bcc, *subject, *body;
+       gchar *from, *to, *cc, *bcc, *subject, *plain_body, *html_body;
+       GList *attachments;
 } MsgData;
 
+typedef struct {
+       gboolean bold;
+       gboolean italics;
+       gboolean bullet;
+       GdkColor color;
+       const gchar *font_family;
+       gint font_size;
+       GtkJustification justification;
+} ModestMsgEditFormatState;
+
 
 /**
  * modest_msg_edit_window_get_type:
@@ -113,6 +129,73 @@ MsgData *               modest_msg_edit_window_get_msg_data          (ModestMsgE
  **/
 void                    modest_msg_edit_window_free_msg_data         (ModestMsgEditWindow *self,
                                                                      MsgData *data);
+
+/**
+ * modest_msg_edit_window_get_format:
+ * @self: a #ModestMsgEditWindow
+ *
+ * obtains the format type of the message body.
+ *
+ * Returns: a #ModestMsgEditFormat
+ **/
+ModestMsgEditFormat     modest_msg_edit_window_get_format            (ModestMsgEditWindow *self);
+
+/**
+ * modest_msg_edit_window_set_format:
+ * @self: a #ModestMsgEditWindow
+ * @format: a #ModestMsgEditFormat
+ *
+ * set the @format of the edit window message body.
+ **/
+void                    modest_msg_edit_window_set_format            (ModestMsgEditWindow *self,
+                                                                     ModestMsgEditFormat format);
+
+/**
+ * modest_msg_edit_window_get_format_state:
+ * @self: a #ModestMsgEditWindow
+ *
+ * get the current format state (the format attributes the text user inserts
+ * will get).
+ *
+ * Returns: a #ModestMsgEditFormatState structure that should be freed with g_free().
+ **/
+ModestMsgEditFormatState *modest_msg_edit_window_get_format_state    (ModestMsgEditWindow *self);
+
+/**
+ * modest_msg_edit_window_set_format_state:
+ * @self: a #ModestMsgEditWindow
+ * @format_state: a #ModestMsgEditWindowFormatState
+ *
+ * sets a new format state (the format attributes the text user inserts 
+ * will get).
+ **/
+void                    modest_msg_edit_window_set_format_state      (ModestMsgEditWindow *self,
+                                                                     const ModestMsgEditFormatState *format_state);
+
+/**
+ * modest_msg_edit_window_select_color:
+ * @self: a #ModestMsgEditWindow
+ *
+ * show color selection dialog and update text color
+ */
+void                    modest_msg_edit_window_select_color          (ModestMsgEditWindow *window);
+
+/**
+ * modest_msg_edit_window_select_background_color:
+ * @self: a #ModestMsgEditWindow
+ *
+ * show color selection dialog and update background color
+ */
+void                    modest_msg_edit_window_select_background_color          (ModestMsgEditWindow *window);
+
+/**
+ * modest_msg_edit_window_insert_image:
+ * @self: a #ModestMsgEditWindow
+ *
+ * show a file selection dialog to insert an image
+ */
+void                    modest_msg_edit_window_insert_image          (ModestMsgEditWindow *window);
+
 G_END_DECLS
 
 #endif /* __MODEST_MSG_EDIT_WINDOW_H__ */
index e726529..ae6112b 100644 (file)
@@ -57,7 +57,7 @@ static void     get_property (GObject *object, guint prop_id, GValue *value, GPa
 
 /* 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);
@@ -113,6 +113,7 @@ struct _ModestMsgViewPrivate {
        /* embedded elements */
        GtkWidget   *headers_box;
        GtkWidget   *html_scroll;
+       GtkWidget   *attachments_box;
 
        /* internal adjustments for set_scroll_adjustments */
        GtkAdjustment *hadj;
@@ -230,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",
@@ -857,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);
@@ -1058,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));
 
@@ -1082,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
@@ -1297,8 +1295,7 @@ modest_msg_view_set_message (ModestMsgView *self, TnyMsg *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));
@@ -1315,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));
index e02dfaf..8e34f4f 100644 (file)
@@ -64,7 +64,7 @@ struct _ModestMsgViewClass {
                                    gpointer user_data);
        void (*link_clicked)       (ModestMsgView *msgview, const gchar* link,
                                    gpointer user_data);
-       void (*attachment_clicked) (ModestMsgView *msgview, int index,
+       void (*attachment_clicked) (ModestMsgView *msgview, TnyMimePart *mime_part,
                                    gpointer user_data);
        void (*recpt_activated)    (ModestMsgView *msgview, const gchar *address,
                                    gpointer user_data);