de5044a1aa000a1b60847a7a4792759234dcfd38
[modest] / src / gnome / modest-msg-edit-window.c
1 /* Copyright (c) 2006, Nokia Corporation
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 #include <glib/gi18n.h>
30 #include <string.h>
31 #include <tny-account-store.h>
32 #include <tny-simple-list.h>
33 #include <modest-conf.h>
34 #include <modest-runtime.h>
35 #include <modest-tny-msg.h>
36
37 #include <widgets/modest-window-priv.h>
38 #include <widgets/modest-msg-edit-window.h>
39 #include <widgets/modest-msg-edit-window-ui.h>
40 #include <widgets/modest-combo-box.h>
41 #include <widgets/modest-attachments-view.h>
42
43 #include <modest-widget-memory.h>
44 #include <modest-account-mgr-helpers.h>
45 #include <modest-tny-folder.h>
46 #include <gtkhtml/gtkhtml.h>
47 #include "modest-msg-edit-window-ui-dimming.h"
48 #include <modest-platform.h>
49 #include <libgnomevfs/gnome-vfs-mime-utils.h>
50 #include <libgnomevfs/gnome-vfs.h>
51 #include <tny-vfs-stream.h>
52 #include <tny-gtk-text-buffer-stream.h>
53 #include <gtksourceview/gtksourceview.h>
54
55 static void  modest_msg_edit_window_class_init   (ModestMsgEditWindowClass *klass);
56 static void  modest_msg_edit_window_init         (ModestMsgEditWindow *obj);
57 static void  modest_msg_edit_window_finalize     (GObject *obj);
58
59 static void  modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
60                                                             ModestMsgEditWindow *window);
61 static void update_next_cid (ModestMsgEditWindow *self, TnyList *attachments);
62
63 /* list my signals */
64 enum {
65         /* MY_SIGNAL_1, */
66         /* MY_SIGNAL_2, */
67         LAST_SIGNAL
68 };
69
70 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
71 struct _ModestMsgEditWindowPrivate {
72
73         GtkWidget   *toolbar;
74         GtkWidget   *menubar;
75
76         GtkWidget   *msg_body;
77         
78         ModestPairList *from_field_protos;
79         GtkWidget   *from_field;
80         
81         GtkWidget   *to_field;
82         GtkWidget   *cc_field;
83         GtkWidget   *bcc_field;
84         GtkWidget   *subject_field;
85
86         GtkWidget   *attachments_view;
87         TnyList     *attachments;
88         guint       next_cid;
89
90         TnyMsg      *draft_msg;
91         TnyMsg      *outbox_msg;
92         gchar       *msg_uid;
93
94         gchar       *references;
95         gchar       *in_reply_to;
96
97         gboolean    sent;
98 };
99
100 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
101                                                     MODEST_TYPE_MSG_EDIT_WINDOW, \
102                                                     ModestMsgEditWindowPrivate))
103 /* globals */
104 static GtkWindowClass *parent_class = NULL;
105
106 /* uncomment the following if you have defined any signals */
107 /* static guint signals[LAST_SIGNAL] = {0}; */
108
109 GType
110 modest_msg_edit_window_get_type (void)
111 {
112         static GType my_type = 0;
113         if (!my_type) {
114                 static const GTypeInfo my_info = {
115                         sizeof(ModestMsgEditWindowClass),
116                         NULL,           /* base init */
117                         NULL,           /* base finalize */
118                         (GClassInitFunc) modest_msg_edit_window_class_init,
119                         NULL,           /* class finalize */
120                         NULL,           /* class data */
121                         sizeof(ModestMsgEditWindow),
122                         1,              /* n_preallocs */
123                         (GInstanceInitFunc) modest_msg_edit_window_init,
124                         NULL
125                 };
126                 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
127                                                   "ModestMsgEditWindow",
128                                                   &my_info, 0);
129         }
130         return my_type;
131 }
132
133
134 static void
135 save_state (ModestWindow *self)
136 {
137         modest_widget_memory_save (modest_runtime_get_conf (),
138                                     G_OBJECT(self), "modest-edit-msg-window");
139 }
140
141
142 static void
143 restore_settings (ModestMsgEditWindow *self)
144 {
145         modest_widget_memory_restore (modest_runtime_get_conf (),
146                                       G_OBJECT(self), "modest-edit-msg-window");
147 }
148
149 static void
150 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
151 {
152         GObjectClass *gobject_class;
153         ModestWindowClass *modest_window_class;
154         
155         gobject_class = (GObjectClass*) klass;
156         modest_window_class = (ModestWindowClass*) klass;
157
158         parent_class            = g_type_class_peek_parent (klass);
159         gobject_class->finalize = modest_msg_edit_window_finalize;
160
161         g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
162
163         modest_window_class->save_state_func = save_state;
164 }
165
166 static void
167 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
168 {
169         ModestMsgEditWindowPrivate *priv;
170         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
171
172         priv->toolbar       = NULL;
173         priv->menubar       = NULL;
174         priv->msg_body      = NULL;
175         priv->from_field    = NULL;
176         priv->to_field      = NULL;
177         priv->cc_field      = NULL;
178         priv->bcc_field     = NULL;
179         priv->subject_field = NULL;
180         priv->attachments_view = NULL;
181         priv->attachments = TNY_LIST (tny_simple_list_new ());
182         priv->sent          = FALSE;
183         priv->next_cid      = 0;
184         priv->draft_msg = NULL;
185         priv->outbox_msg = NULL;
186         priv->msg_uid = NULL;
187         priv->references = NULL;
188         priv->in_reply_to = NULL;
189 }
190
191 /** 
192  * @result: A ModestPairList, which must be freed with modest_pair_list_free().
193  */
194 static ModestPairList*
195 get_transports (void)
196 {
197         ModestAccountMgr *account_mgr;
198         GSList *transports = NULL;
199         GSList *cursor, *accounts;
200         
201         account_mgr = modest_runtime_get_account_mgr();
202         cursor = accounts = modest_account_mgr_account_names (account_mgr, TRUE);
203         while (cursor) {
204                 gchar *account_name = cursor->data ? g_strdup((gchar*)cursor->data) : NULL;
205                 gchar *from_string  = modest_account_mgr_get_from_string (account_mgr,
206                                                                           account_name, NULL);
207                 if (!from_string)  {
208                         /* something went wrong: ignore this one */
209                         g_free (account_name);
210                         cursor->data = NULL;
211                 } else {
212                         ModestPair *pair;
213                         pair = modest_pair_new ((gpointer) account_name,
214                                                 (gpointer) from_string , TRUE);
215                         transports = g_slist_prepend (transports, pair);
216                 } /* don't free account name; it's freed when the transports list is freed */
217                 cursor = cursor->next;
218         }
219         g_slist_free (accounts);
220         return transports;
221 }
222
223
224 static void
225 on_from_combo_changed (ModestComboBox *combo, ModestWindow *win)
226 {
227         modest_window_set_active_account (
228                 win, modest_combo_box_get_active_id(combo));
229 }
230
231
232
233 static void
234 init_window (ModestMsgEditWindow *obj, const gchar* account)
235 {
236         GtkWidget *to_button, *cc_button, *bcc_button, *add_attachment_button; 
237         GtkWidget *header_table;
238         GtkWidget *main_vbox;
239         GtkWidget *msg_vbox;
240         GtkWidget *scrolled_window;
241         ModestMsgEditWindowPrivate *priv;
242         ModestWindowPrivate *parent_priv;
243         
244         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
245         parent_priv = MODEST_WINDOW_GET_PRIVATE(obj);
246
247         to_button     = gtk_button_new_with_label (_("To..."));
248         cc_button     = gtk_button_new_with_label (_("Cc..."));
249         bcc_button    = gtk_button_new_with_label (_("Bcc..."));
250         add_attachment_button = gtk_button_new_with_label (_("Attach..."));
251         
252         /* Note: This ModestPairList* must exist for as long as the combo
253          * that uses it, because the ModestComboBox uses the ID opaquely, 
254          * so it can't know how to manage its memory. */ 
255         priv->from_field_protos = get_transports ();
256         priv->from_field    = modest_combo_box_new (priv->from_field_protos, g_str_equal);
257         
258         if (account) {
259                 modest_combo_box_set_active_id (MODEST_COMBO_BOX(priv->from_field),
260                                                 (gpointer)account);
261                 modest_window_set_active_account (MODEST_WINDOW(obj), account);
262         }
263         /* auto-update the active account */
264         g_signal_connect (G_OBJECT(priv->from_field), "changed", G_CALLBACK(on_from_combo_changed), obj);
265         
266         priv->to_field      = gtk_entry_new_with_max_length (80);
267         priv->cc_field      = gtk_entry_new_with_max_length (80);
268         priv->bcc_field     = gtk_entry_new_with_max_length (80);
269         priv->subject_field = gtk_entry_new_with_max_length (80);
270         priv->attachments_view = modest_attachments_view_new (NULL);
271         
272         header_table = gtk_table_new (6,2, FALSE);
273         
274         gtk_table_attach (GTK_TABLE(header_table), gtk_label_new (_("From:")),
275                           0,1,0,1, GTK_FILL, 0, 0, 0);
276         gtk_table_attach (GTK_TABLE(header_table), to_button,     0,1,1,2, GTK_FILL, 0, 0, 0);
277         gtk_table_attach (GTK_TABLE(header_table), cc_button,     0,1,2,3, GTK_FILL, 0, 0, 0);
278         gtk_table_attach (GTK_TABLE(header_table), bcc_button,    0,1,3,4, GTK_FILL, 0, 0, 0);
279         gtk_table_attach (GTK_TABLE(header_table), gtk_label_new (_("Subject:")),
280                           0,1,4,5, GTK_FILL, 0, 0, 0);
281         gtk_table_attach (GTK_TABLE(header_table), add_attachment_button, 0, 1, 5, 6, GTK_FILL, 0, 0, 0);
282
283         gtk_table_attach_defaults (GTK_TABLE(header_table), priv->from_field,   1,2,0,1);
284         gtk_table_attach_defaults (GTK_TABLE(header_table), priv->to_field,     1,2,1,2);
285         gtk_table_attach_defaults (GTK_TABLE(header_table), priv->cc_field,     1,2,2,3);
286         gtk_table_attach_defaults (GTK_TABLE(header_table), priv->bcc_field,    1,2,3,4);
287         gtk_table_attach_defaults (GTK_TABLE(header_table), priv->subject_field,1,2,4,5);
288         gtk_table_attach_defaults (GTK_TABLE(header_table), priv->attachments_view,1,2,5,6);
289
290         priv->msg_body = gtk_source_view_new ();
291         gtk_source_view_set_highlight_current_line (GTK_SOURCE_VIEW (priv->msg_body), TRUE);
292         gtk_source_view_set_right_margin_position (GTK_SOURCE_VIEW (priv->msg_body), 78);
293         gtk_source_view_set_show_right_margin (GTK_SOURCE_VIEW (priv->msg_body), TRUE);
294         gtk_text_view_set_editable (GTK_TEXT_VIEW (priv->msg_body), TRUE);
295         gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
296
297         PangoFontDescription *font_desc;
298         font_desc = pango_font_description_from_string ("Monospace");
299         gtk_widget_modify_font (priv->msg_body, font_desc);
300         pango_font_description_free (font_desc);
301         
302         main_vbox = gtk_vbox_new  (FALSE, 0);
303
304         scrolled_window = gtk_scrolled_window_new (NULL, NULL);
305         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), 
306                                         GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
307         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
308
309         gtk_box_pack_start (GTK_BOX(main_vbox), priv->menubar, FALSE, FALSE, 0);
310         gtk_box_pack_start (GTK_BOX(main_vbox), priv->toolbar, FALSE, FALSE, 0);
311         
312         msg_vbox = gtk_vbox_new (FALSE, 0);
313         gtk_box_pack_start (GTK_BOX (main_vbox), msg_vbox, TRUE, TRUE, 0);
314
315         gtk_box_pack_start (GTK_BOX(msg_vbox), header_table, FALSE, FALSE, 0);
316         gtk_container_add (GTK_CONTAINER (scrolled_window), priv->msg_body); 
317
318         gtk_box_pack_start (GTK_BOX(msg_vbox), scrolled_window, TRUE, TRUE, 0);
319
320         gtk_widget_show_all (GTK_WIDGET(main_vbox));
321         gtk_container_add (GTK_CONTAINER(obj), main_vbox);
322
323         g_signal_connect_object (add_attachment_button, "clicked", 
324                                  G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), G_OBJECT (obj), 0);
325 }
326
327
328 static void
329 modest_msg_edit_window_finalize (GObject *obj)
330 {
331         ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
332         
333         /* These had to stay alive for as long as the comboboxes that used them: */
334         modest_pair_list_free (priv->from_field_protos);
335         g_object_unref (priv->attachments);
336         priv->attachments = NULL;
337
338         if (priv->draft_msg != NULL) {
339                 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
340                 if (TNY_IS_HEADER (header)) {
341                         ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
342                         modest_window_mgr_unregister_header (mgr, header);
343                 }
344                 g_object_unref (priv->draft_msg);
345                 priv->draft_msg = NULL;
346         }
347         if (priv->outbox_msg != NULL) {
348                 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
349                 if (TNY_IS_HEADER (header)) {
350                         ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
351                         modest_window_mgr_unregister_header (mgr, header);
352                 }
353                 g_object_unref (priv->outbox_msg);
354                 priv->outbox_msg = NULL;
355         }
356         g_free (priv->msg_uid);
357         g_free (priv->references);
358         g_free (priv->in_reply_to);
359         
360         G_OBJECT_CLASS(parent_class)->finalize (obj);
361 }
362
363 static void
364 update_next_cid (ModestMsgEditWindow *self, TnyList *attachments)
365 {
366         TnyIterator *iter;
367         ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
368
369         for (iter = tny_list_create_iterator (attachments) ; 
370              !tny_iterator_is_done (iter);
371              tny_iterator_next (iter)) {
372                 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
373                 const gchar *cid = tny_mime_part_get_content_id (part);
374                 if (cid != NULL) {
375                         char *invalid = NULL;
376                         gint int_cid = strtol (cid, &invalid, 10);
377                         if ((invalid != NULL) && (*invalid == '\0') && (int_cid >= priv->next_cid)) {
378                                 priv->next_cid = int_cid + 1;
379                         }
380                 }
381                 g_object_unref (part);
382         }
383         g_object_unref (iter);
384 }
385
386
387
388 static gboolean
389 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
390 {
391         modest_window_save_state (MODEST_WINDOW(self));
392         return FALSE;
393 }
394
395
396 static void
397 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
398 {
399         TnyHeader *header;
400         TnyFolder *msg_folder;
401         gchar *to, *cc, *bcc, *subject;
402         ModestMsgEditWindowPrivate *priv;
403         TnyMimePart *body_part;
404         GtkTextBuffer *buffer;
405         
406         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
407         g_return_if_fail (TNY_IS_MSG (msg));
408
409         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
410
411         header  = tny_msg_get_header (msg);
412         to      = tny_header_dup_to (header);
413         cc      = tny_header_dup_cc (header);
414         bcc     = tny_header_dup_bcc (header);
415         subject = tny_header_dup_subject (header);
416
417         if (to)
418                 gtk_entry_set_text (GTK_ENTRY(priv->to_field), to);
419         if (cc)
420                 gtk_entry_set_text (GTK_ENTRY(priv->cc_field), cc);
421         if (bcc)
422                 gtk_entry_set_text (GTK_ENTRY(priv->bcc_field),  bcc);
423         if (subject)
424                 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
425
426         modest_tny_msg_get_references (TNY_MSG (msg), NULL, &(priv->references), &(priv->in_reply_to));
427
428         modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
429         priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
430         update_next_cid (self, priv->attachments);
431
432         body_part = modest_tny_msg_find_body_part  (msg, FALSE);
433         if (body_part) {
434                 TnyStream *stream;
435                 gtk_text_view_set_editable (GTK_TEXT_VIEW (priv->msg_body), FALSE);
436                 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
437                 stream = TNY_STREAM (tny_gtk_text_buffer_stream_new (buffer));
438                 tny_stream_reset (stream);
439                 tny_mime_part_decode_to_stream (body_part, stream, NULL);
440                 tny_stream_reset (stream);
441                 gtk_text_view_set_editable (GTK_TEXT_VIEW (priv->msg_body), TRUE);
442         }
443
444         modest_msg_edit_window_set_modified (self, FALSE);
445
446         if (priv->msg_uid) {
447                 g_free (priv->msg_uid);
448                 priv->msg_uid = NULL;
449         }
450
451         /* we should set a reference to the incoming message if it is a draft */
452         msg_folder = tny_msg_get_folder (msg);
453         if (msg_folder) {               
454                 if (modest_tny_folder_is_local_folder (msg_folder)) {
455                         TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
456                         if (type == TNY_FOLDER_TYPE_INVALID)
457                                 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
458                         
459                         if (type == TNY_FOLDER_TYPE_DRAFTS) 
460                                 priv->draft_msg = g_object_ref(msg);
461                         if (type == TNY_FOLDER_TYPE_OUTBOX)
462                                 priv->outbox_msg = g_object_ref(msg);
463                         priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
464                 }
465                 g_object_unref (msg_folder);
466         }
467
468         g_free (subject);
469         g_free (to);
470         g_free (cc);
471         g_free (bcc);
472 }
473
474
475 ModestWindow *
476 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account,
477                             const gchar *mailbox,
478                             gboolean preserve_is_rich)
479 {
480         ModestMsgEditWindow *self;
481         ModestMsgEditWindowPrivate *priv;
482         ModestWindowPrivate *parent_priv;
483         GtkActionGroup *action_group;
484         ModestDimmingRulesGroup *menu_rules_group = NULL;
485         ModestDimmingRulesGroup *toolbar_rules_group = NULL;
486         ModestDimmingRulesGroup *clipboard_rules_group = NULL;
487         GError *error = NULL;
488
489         g_return_val_if_fail (msg, NULL);
490         
491         self = MODEST_MSG_EDIT_WINDOW(g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL));
492         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(self);
493         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
494         
495         parent_priv->ui_manager = gtk_ui_manager_new();
496         action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
497         gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
498
499         /* Add common actions */
500         gtk_action_group_add_actions (action_group,
501                                       modest_msg_edit_action_entries,
502                                       G_N_ELEMENTS (modest_msg_edit_action_entries),
503                                       self);
504         gtk_action_group_add_toggle_actions (action_group,
505                                              modest_msg_edit_toggle_action_entries,
506                                              G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
507                                              self);
508         gtk_action_group_add_radio_actions (action_group,
509                                             modest_msg_edit_priority_action_entries,
510                                             G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
511                                             0,
512                                             G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
513                                             self);
514         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
515         g_object_unref (action_group);
516
517         /* Load the UI definition */
518         gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
519                                          MODEST_UIDIR "modest-msg-edit-window-ui.xml",
520                                          &error);
521         if (error) {
522                 g_printerr ("modest: could not merge modest-msg-edit-window-ui.xml: %s\n", error->message);
523                 g_error_free (error);
524                 error = NULL;
525         }
526         /* ****** */
527
528         /* Add accelerators */
529         gtk_window_add_accel_group (GTK_WINDOW (self), 
530                                     gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
531
532         /* Toolbar / Menubar */
533         priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
534         priv->menubar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar");
535
536         gtk_toolbar_set_tooltips (GTK_TOOLBAR (priv->toolbar), TRUE);
537
538         /* Init window */
539         init_window (MODEST_MSG_EDIT_WINDOW(self), account);
540
541         restore_settings (MODEST_MSG_EDIT_WINDOW(self));
542         
543         gtk_window_set_title (GTK_WINDOW(self), "Modest");
544         gtk_window_set_icon_from_file (GTK_WINDOW(self), MODEST_APP_ICON, NULL);
545
546         g_signal_connect (G_OBJECT(self), "delete-event",
547                           G_CALLBACK(on_delete_event), self);
548         
549         parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new ();
550         menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
551         toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
552         clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
553
554         /* Add common dimming rules */
555         modest_dimming_rules_group_add_rules (menu_rules_group, 
556                                               modest_msg_edit_window_menu_dimming_entries,
557                                               G_N_ELEMENTS (modest_msg_edit_window_menu_dimming_entries),
558                                               MODEST_WINDOW (self));
559         modest_dimming_rules_group_add_rules (toolbar_rules_group, 
560                                               modest_msg_edit_window_toolbar_dimming_entries,
561                                               G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
562                                               MODEST_WINDOW (self));
563 /*      modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_button, */
564 /*                                                  G_CALLBACK (modest_ui_dimming_rules_on_set_style), */
565 /*                                                  MODEST_WINDOW (self)); */
566 /*      modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem, */
567 /*                                                  G_CALLBACK (modest_ui_dimming_rules_on_set_style), */
568 /*                                                  MODEST_WINDOW (self)); */
569 /*      modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem, */
570 /*                                                  G_CALLBACK (modest_ui_dimming_rules_on_set_style), */
571 /*                                                  MODEST_WINDOW (self)); */
572         modest_dimming_rules_group_add_rules (clipboard_rules_group, 
573                                               modest_msg_edit_window_clipboard_dimming_entries,
574                                               G_N_ELEMENTS (modest_msg_edit_window_clipboard_dimming_entries),
575                                               MODEST_WINDOW (self));
576         /* Insert dimming rules group for this window */
577         modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
578         modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
579         modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
580         /* Checks the dimming rules */
581         g_object_unref (menu_rules_group);
582         g_object_unref (toolbar_rules_group);
583         g_object_unref (clipboard_rules_group);
584
585         set_msg (self, msg);
586         
587         return MODEST_WINDOW(self);
588 }
589
590
591 MsgData * 
592 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
593 {
594         MsgData *data;
595         
596         const gchar *account_name;
597         gchar *from_string = NULL;
598         ModestMsgEditWindowPrivate *priv;
599         TnyIterator *att_iter;
600         
601         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
602
603         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
604         
605         account_name = (gchar*)modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
606         if (account_name) 
607                 from_string = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), 
608                                                                   account_name, NULL);
609         if (!from_string) {
610                 g_printerr ("modest: cannot get from string\n");
611                 return NULL;
612         }
613         
614         
615         
616         data = g_slice_new0 (MsgData);
617         data->from    =  from_string; /* will be freed when data is freed */
618         data->to      =  g_strdup ( gtk_entry_get_text (GTK_ENTRY(priv->to_field)));
619         data->cc      =  g_strdup ( gtk_entry_get_text (GTK_ENTRY(priv->cc_field)));
620         data->bcc     =  g_strdup ( gtk_entry_get_text (GTK_ENTRY(priv->bcc_field)));
621         data->subject =  g_strdup ( gtk_entry_get_text (GTK_ENTRY(priv->subject_field)));
622         data->references = g_strdup (priv->references);
623         data->in_reply_to = g_strdup (priv->in_reply_to);
624
625         GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
626         GtkTextIter b, e;
627         gtk_text_buffer_get_bounds (buf, &b, &e);
628         data->plain_body =  gtk_text_buffer_get_text (buf, &b, &e, FALSE); /* Returns a copy. */
629         data->html_body = NULL;
630
631         /* deep-copy the attachment data */
632         att_iter = tny_list_create_iterator (priv->attachments);
633         data->attachments = NULL;
634         while (!tny_iterator_is_done (att_iter)) {
635                 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
636                 if (!(TNY_IS_MIME_PART(part))) {
637                         g_warning ("strange data in attachment list");
638                         g_object_unref (part);
639                         tny_iterator_next (att_iter);
640                         continue;
641                 }
642                 data->attachments = g_list_append (data->attachments,
643                                                    part);
644                 tny_iterator_next (att_iter);
645         }
646         g_object_unref (att_iter);
647
648
649         if (priv->draft_msg) {
650                 data->draft_msg = g_object_ref (priv->draft_msg);
651         } else if (priv->outbox_msg) {
652                 data->draft_msg = g_object_ref (priv->outbox_msg);
653         } else {
654                 data->draft_msg = NULL;
655         }
656         return data;
657 }
658
659 static void
660 unref_gobject (GObject *obj, gpointer data)
661 {
662         if (!G_IS_OBJECT(obj))
663                 return;
664         g_object_unref (obj);
665 }
666
667 void 
668 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
669                                       MsgData *data)
670 {
671         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
672
673         if (!data)
674                 return;
675
676         g_free (data->to);
677         g_free (data->cc);
678         g_free (data->bcc);
679         g_free (data->subject);
680         g_free (data->plain_body);
681         g_free (data->html_body);
682         g_free (data->references);
683         g_free (data->in_reply_to);
684
685         if (data->draft_msg != NULL) {
686                 g_object_unref (data->draft_msg);
687                 data->draft_msg = NULL;
688         }       
689         
690         g_list_foreach (data->attachments, (GFunc)unref_gobject,  NULL);
691         g_list_free (data->attachments);
692
693         g_slice_free (MsgData, data);
694 }
695
696 /* Rich formatting API functions */
697 ModestMsgEditFormat
698 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
699 {
700         return MODEST_MSG_EDIT_FORMAT_TEXT;
701 }
702
703 void
704 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
705                                    ModestMsgEditFormat format)
706 {
707         switch (format) {
708         case MODEST_MSG_EDIT_FORMAT_TEXT:
709                 break;
710         case MODEST_MSG_EDIT_FORMAT_HTML:
711                 g_message ("HTML format not supported in Gnome ModestMsgEditWindow");
712                 break;
713         default:
714                 break;
715         }
716 }
717
718 ModestMsgEditFormatState *
719 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
720 {
721         ModestMsgEditFormatState *format_state;
722
723         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
724
725         format_state = g_new0 (ModestMsgEditFormatState, 1);
726
727         return format_state;
728 }
729
730 void
731 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self, 
732                                          const ModestMsgEditFormatState *format_state)
733 {
734         g_return_if_fail (MODEST_MSG_EDIT_WINDOW (self));
735
736         /* Ends silently as set_format_state should do nothing when edit window format
737            is not HTML */
738         return;
739 }
740
741 void
742 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
743 {
744         g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
745
746         g_message ("Select color operation is not supported");
747 }
748
749 void
750 modest_msg_edit_window_select_file_format (ModestMsgEditWindow *window,
751                                            gint file_format)
752 {
753         g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
754
755         g_message ("Select file format operation is not supported");
756 }
757
758 void
759 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
760 {
761         g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
762
763         g_message ("Select font operation is not supported");
764 }
765
766 void
767 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
768 {
769         g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
770
771         g_message ("Select background color operation is not supported");
772 }
773
774 void
775 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
776 {
777         g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
778
779         g_message ("Insert image operation is not supported");
780 }
781
782 void
783 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
784 {
785         g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
786
787         g_message ("Attach file operation is not supported");
788 }
789
790 void
791 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
792                                            TnyList *att_list)
793 {
794         ModestMsgEditWindowPrivate *priv;
795         TnyIterator *iter;
796
797         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
798         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
799
800         if (att_list == NULL) {
801                 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
802         } else {
803                 g_object_ref (att_list);
804         }
805
806         if (tny_list_get_length (att_list) == 0) {
807                 modest_platform_information_banner (NULL, NULL, _("TODO: no attachments selected to remove"));
808         } else {
809                 GtkWidget *confirmation_dialog = NULL;
810                 gboolean dialog_response;
811                 gchar *message = NULL;
812                 gchar *filename = NULL;
813
814                 if (tny_list_get_length (att_list) == 1) {
815                         TnyMimePart *part;
816                         iter = tny_list_create_iterator (att_list);
817                         part = (TnyMimePart *) tny_iterator_get_current (iter);
818                         g_object_unref (iter);
819                         if (TNY_IS_MSG (part)) {
820                                 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
821                                 if (header) {
822                                         filename = tny_header_dup_subject (header);
823                                         g_object_unref (header);
824                                 }
825                                 if (filename == NULL) {
826                                         filename = g_strdup (_("mail_va_no_subject"));
827                                 }
828                         } else {
829                                 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
830                         }
831                         g_object_unref (part);
832                 } else {
833                         filename = g_strdup ("");
834                 }
835                 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
836                                                     (tny_list_get_length (att_list) == 1)), filename);
837                 g_free (filename);
838                 confirmation_dialog = gtk_message_dialog_new (GTK_WINDOW (window), 
839                                                               GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, 
840                                                               GTK_MESSAGE_QUESTION,
841                                                               GTK_BUTTONS_OK_CANCEL,
842                                                               "%s", message);
843                 g_free (message);
844                 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
845                 gtk_widget_destroy (confirmation_dialog);
846                 if (!dialog_response) {
847                         g_object_unref (att_list);
848                         return;
849                 }
850                 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
851                 
852                 for (iter = tny_list_create_iterator (att_list);
853                      !tny_iterator_is_done (iter);
854                      tny_iterator_next (iter)) {
855                         TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
856                         tny_list_remove (priv->attachments, (GObject *) mime_part);
857
858                         modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
859                                                                    mime_part);
860                         g_object_unref (mime_part);
861                 }
862                 g_object_unref (iter);
863         }
864
865         g_object_unref (att_list);
866
867 }
868
869 static void
870 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
871                                                ModestMsgEditWindow *window)
872 {
873         modest_msg_edit_window_offer_attach_file (window);
874 }
875
876 void 
877 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
878                                        gint *parts_count,
879                                        guint64 *parts_size)
880 {
881         ModestMsgEditWindowPrivate *priv;
882
883         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
884
885         modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
886
887 }
888
889 void
890 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window, 
891                                 gboolean show)
892 {
893         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
894
895         g_message ("not implemented yet %s", __FUNCTION__);
896 }
897 void
898 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window, 
899                                 gboolean show)
900 {
901         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
902
903         g_message ("not implemented yet %s", __FUNCTION__);
904 }
905 void
906 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
907 {
908         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
909       
910         g_message ("not implemented yet %s", __FUNCTION__);
911 }
912 void
913 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
914 {
915         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
916       
917         g_message ("not implemented yet %s", __FUNCTION__);
918 }
919 void
920 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
921                                            TnyHeaderFlags priority_flags)
922 {
923         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
924       
925         g_message ("not implemented yet %s", __FUNCTION__);
926 }
927
928
929 void
930 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
931 {
932         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
933
934         g_message ("not implemented yet %s", __FUNCTION__);
935 }
936
937 gboolean
938 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
939 {
940         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
941
942         g_message ("not implemented yet %s", __FUNCTION__);
943         return TRUE;
944 }
945
946 void
947 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
948                                         gint file_format)
949 {
950         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
951
952         g_message ("not implemented yet %s", __FUNCTION__);
953 }
954
955 gboolean 
956 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
957 {
958         ModestMsgEditWindowPrivate *priv;
959
960         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
961         return priv->sent;
962 }
963
964 void 
965 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window, 
966                                  gboolean sent)
967 {
968         ModestMsgEditWindowPrivate *priv;
969
970         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
971         priv->sent = sent;
972 }
973
974 GtkWidget *
975 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
976                                          ModestMsgEditWindowWidgetType widget_type)
977 {
978         ModestMsgEditWindowPrivate *priv;
979
980         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
981         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
982
983         switch (widget_type) {
984         case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
985                 return priv->msg_body;
986                 break;
987         case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
988                 return priv->to_field;
989                 break;
990         case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
991                 return priv->cc_field;
992                 break;
993         case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
994                 return priv->bcc_field;
995                 break;
996         case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
997                 return priv->subject_field;
998                 break;
999         case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
1000                 return priv->attachments_view;
1001                 break;
1002         default:
1003                 return NULL;
1004         }
1005         return NULL;
1006 }
1007
1008 /* FUNCTIONS NOT IMPLEMENTED YET */
1009
1010 void            
1011 modest_msg_edit_window_set_modified      (ModestMsgEditWindow *window,
1012                                           gboolean modified)
1013 {
1014         g_message (__FUNCTION__);
1015 }
1016
1017 void            
1018 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
1019                                             gboolean show)
1020 {
1021         g_message ("NOT IMPLEMENTED %s", __FUNCTION__);
1022 }
1023
1024 void                    
1025 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
1026                                  TnyMimePart *part)
1027 {
1028         ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1029
1030         g_return_if_fail (TNY_IS_MIME_PART (part));
1031         tny_list_prepend (priv->attachments, (GObject *) part);
1032         modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
1033 }
1034
1035 void            
1036 modest_msg_edit_window_redo               (ModestMsgEditWindow *window)
1037 {
1038         g_message ("NOT IMPLEMENTED %s", __FUNCTION__);
1039 }
1040
1041 void                    
1042 modest_msg_edit_window_offer_attach_file           (ModestMsgEditWindow *window)
1043 {
1044         GtkWidget *dialog = NULL;
1045         gint response = 0;
1046         GSList *uris = NULL;
1047         GSList *uri_node;
1048         
1049         dialog = gtk_file_chooser_dialog_new (_("mcen_ti_select_attachment_title"), 
1050                                               GTK_WINDOW (window), 
1051                                               GTK_FILE_CHOOSER_ACTION_OPEN,
1052                                               GTK_STOCK_OPEN,
1053                                               GTK_RESPONSE_OK,
1054                                               GTK_STOCK_CANCEL,
1055                                               GTK_RESPONSE_CANCEL,
1056                                               NULL);
1057
1058         response = gtk_dialog_run (GTK_DIALOG (dialog));
1059         switch (response) {
1060         case GTK_RESPONSE_OK:
1061                 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1062                 break;
1063         default:
1064                 break;
1065         }
1066         gtk_widget_destroy (dialog);
1067
1068         for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1069                 const gchar *uri = (const gchar *) uri_node->data;
1070                 modest_msg_edit_window_attach_file_one (window, uri, MODEST_MAX_ATTACHMENT_SIZE);
1071         }
1072         g_slist_foreach (uris, (GFunc) g_free, NULL);
1073         g_slist_free (uris);
1074 }
1075
1076 GnomeVFSFileSize
1077 modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window, 
1078                                         const gchar *uri,
1079                                         GnomeVFSFileSize allowed_size)
1080 {
1081         GnomeVFSHandle *handle = NULL;
1082         ModestMsgEditWindowPrivate *priv;
1083         GnomeVFSResult result;
1084
1085         g_return_val_if_fail (window, 0);
1086         g_return_val_if_fail (uri, 0);
1087                 
1088         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1089         
1090         result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1091         if (result == GNOME_VFS_OK) {
1092                 TnyMimePart *mime_part;
1093                 TnyStream *stream;
1094                 const gchar *mime_type = NULL;
1095                 gchar *basename;
1096                 gchar *escaped_filename;
1097                 gchar *filename;
1098                 gchar *content_id;
1099                 GnomeVFSFileInfo *info;
1100                 GnomeVFSURI *vfs_uri;
1101
1102                 vfs_uri = gnome_vfs_uri_new (uri);
1103
1104                 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
1105                 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
1106                 g_free (escaped_filename);
1107                 gnome_vfs_uri_unref (vfs_uri);
1108
1109                 info = gnome_vfs_file_info_new ();
1110                 
1111                 if (gnome_vfs_get_file_info (uri, 
1112                                              info, 
1113                                              GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1114                     == GNOME_VFS_OK)
1115                         mime_type = gnome_vfs_file_info_get_mime_type (info);
1116                 mime_part = tny_platform_factory_new_mime_part
1117                         (modest_runtime_get_platform_factory ());
1118                 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1119                 
1120                 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
1121
1122                 g_object_unref (stream);
1123                 
1124                 content_id = g_strdup_printf ("%d", priv->next_cid);
1125                 tny_mime_part_set_content_id (mime_part, content_id);
1126                 g_free (content_id);
1127                 priv->next_cid++;
1128                 
1129                 basename = g_path_get_basename (filename);
1130                 tny_mime_part_set_filename (mime_part, basename);
1131                 g_free (basename);
1132                 
1133                 tny_list_prepend (priv->attachments, (GObject *) mime_part);
1134                 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1135                                                         mime_part,
1136                                                         info->size == 0, info->size);
1137                 g_free (filename);
1138                 g_object_unref (mime_part);
1139                 gnome_vfs_file_info_unref (info);
1140         }
1141         /* TODO: return proper file size */
1142         return 0;
1143 }
1144
1145 void            
1146 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
1147                                   TnyMsg *draft)
1148 {
1149         ModestMsgEditWindowPrivate *priv;
1150         TnyHeader *header = NULL;
1151
1152         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1153         g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
1154
1155         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1156         ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1157
1158         if (priv->draft_msg != NULL) {
1159                 g_object_unref (priv->draft_msg);
1160         }
1161
1162         if (draft != NULL) {
1163                 g_object_ref (draft);
1164                 header = tny_msg_get_header (draft);
1165                 if (priv->msg_uid) {
1166                         g_free (priv->msg_uid);
1167                         priv->msg_uid = NULL;
1168                 }
1169                 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1170                 if (GTK_WIDGET_REALIZED (window))
1171                         modest_window_mgr_register_window (mgr, MODEST_WINDOW (window), NULL);
1172         }
1173
1174         priv->draft_msg = draft;
1175 }
1176
1177 gboolean        
1178 modest_msg_edit_window_is_modified         (ModestMsgEditWindow *window)
1179 {
1180         g_message ("NOT IMPLEMENTED %s", __FUNCTION__);
1181         return TRUE;
1182 }
1183
1184 const gchar *
1185 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
1186 {
1187         g_message ("NOT IMPLEMENTED %s", __FUNCTION__);
1188         return NULL;
1189 }
1190
1191 gboolean            
1192 modest_msg_edit_window_can_redo               (ModestMsgEditWindow *window)
1193 {
1194         g_message ("NOT IMPLEMENTED %s", __FUNCTION__);
1195         return FALSE;
1196 }
1197 gboolean            
1198 modest_msg_edit_window_can_undo               (ModestMsgEditWindow *window)
1199 {
1200         g_message ("NOT IMPLEMENTED %s", __FUNCTION__);
1201         return FALSE;
1202 }
1203
1204 const gchar*    
1205 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
1206 {
1207         ModestMsgEditWindowPrivate *priv;
1208
1209         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);        
1210         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1211
1212         return priv->msg_uid;
1213 }