053e2bfd68401cae5a95867a98a5b2f1454c05e4
[modest] / src / maemo / 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
30 #include <gtk/gtk.h>
31 #include <glib/gi18n.h>
32 #include <fcntl.h>
33 #include <glib/gstdio.h>
34 #include <string.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37
38 #include <config.h>
39
40 #include <modest-account-mgr.h>
41 #include <modest-account-mgr-helpers.h>
42
43 #include <widgets/modest-msg-edit-window.h>
44 #include <widgets/modest-combo-box.h>
45 #include <widgets/modest-recpt-editor.h>
46 #include <widgets/modest-attachments-view.h>
47
48 #include <modest-runtime.h>
49
50 #include "modest-platform.h"
51 #include "modest-icon-names.h"
52 #include "modest-widget-memory.h"
53 #include "modest-window-priv.h"
54 #include "modest-mail-operation.h"
55 #include "modest-tny-platform-factory.h"
56 #include "modest-tny-msg.h"
57 #include "modest-address-book.h"
58 #include <tny-simple-list.h>
59 #include <wptextview.h>
60 #include <wptextbuffer.h>
61 #include <hildon-widgets/hildon-color-selector.h>
62 #include <hildon-widgets/hildon-color-button.h>
63 #include <hildon-widgets/hildon-banner.h>
64 #include <hildon-widgets/hildon-caption.h>
65 #include <hildon-widgets/hildon-scroll-area.h>
66 #include "widgets/modest-msg-edit-window-ui.h"
67
68 #ifdef MODEST_HILDON_VERSION_0
69 #include <hildon-widgets/hildon-file-chooser-dialog.h>
70 #else
71 #include <hildon/hildon-file-chooser-dialog.h>
72
73 #endif /*MODEST_HILDON_VERSION_0 */
74
75
76
77 #define DEFAULT_FONT_SIZE 3
78 #define DEFAULT_FONT 2
79 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
80 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
81 #define DEFAULT_MAIN_VBOX_SPACING 6
82 #define SUBJECT_MAX_LENGTH 1000
83
84 static void  modest_msg_edit_window_class_init   (ModestMsgEditWindowClass *klass);
85 static void  modest_msg_edit_window_init         (ModestMsgEditWindow *obj);
86 static void  modest_msg_edit_window_finalize     (GObject *obj);
87
88 static void  text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
89 static void  text_buffer_mark_set (GtkTextBuffer *buffer, GtkTextIter *location, GtkTextMark *mark, gpointer userdata);
90 static void  modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
91                                                          gpointer userdata);
92 static void  modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
93                                                  gpointer userdata);
94 static void  modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
95                                                  gpointer userdata);
96 static void  modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
97 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget, 
98                                                            GdkEventWindowState *event, 
99                                                            gpointer userdata);
100 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
101                                                      ModestRecptEditor *editor);
102
103 /* ModestWindow methods implementation */
104 static void  modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
105 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
106 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
107 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
108 static void modest_msg_edit_window_show_toolbar   (ModestWindow *window,
109                                                    gboolean show_toolbar);
110
111
112 /* list my signals */
113 enum {
114         /* MY_SIGNAL_1, */
115         /* MY_SIGNAL_2, */
116         LAST_SIGNAL
117 };
118
119 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
120 struct _ModestMsgEditWindowPrivate {
121         GtkWidget   *msg_body;
122         GtkWidget   *header_box;
123         GtkWidget   *from_field;
124         GtkWidget   *to_field;
125         GtkWidget   *cc_field;
126         GtkWidget   *bcc_field;
127         GtkWidget   *subject_field;
128         GtkWidget   *attachments_view;
129         GtkWidget   *priority_icon;
130         GtkWidget   *add_attachment_button;
131
132         GtkWidget   *cc_caption;
133         GtkWidget   *bcc_caption;
134         GtkWidget   *attachments_caption;
135
136         GtkTextBuffer *text_buffer;
137
138         GtkWidget   *font_color_button;
139         GSList      *font_items_group;
140         GtkWidget   *font_tool_button_label;
141         GSList      *size_items_group;
142         GtkWidget   *size_tool_button_label;
143
144         GtkWidget   *scroll;
145
146         gint last_cid;
147         GList *attachments;
148
149         TnyHeaderFlags priority_flags;
150
151         gdouble zoom_level;
152 };
153
154 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
155                                                     MODEST_TYPE_MSG_EDIT_WINDOW, \
156                                                     ModestMsgEditWindowPrivate))
157 /* globals */
158 static GtkWindowClass *parent_class = NULL;
159
160 /* uncomment the following if you have defined any signals */
161 /* static guint signals[LAST_SIGNAL] = {0}; */
162
163 GType
164 modest_msg_edit_window_get_type (void)
165 {
166         static GType my_type = 0;
167         if (!my_type) {
168                 static const GTypeInfo my_info = {
169                         sizeof(ModestMsgEditWindowClass),
170                         NULL,           /* base init */
171                         NULL,           /* base finalize */
172                         (GClassInitFunc) modest_msg_edit_window_class_init,
173                         NULL,           /* class finalize */
174                         NULL,           /* class data */
175                         sizeof(ModestMsgEditWindow),
176                         1,              /* n_preallocs */
177                         (GInstanceInitFunc) modest_msg_edit_window_init,
178                         NULL
179                 };
180                 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
181                                                   "ModestMsgEditWindow",
182                                                   &my_info, 0);
183
184                 wp_text_buffer_library_init ();
185         }
186         return my_type;
187 }
188
189 static void
190 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
191 {
192         GObjectClass *gobject_class;
193         ModestWindowClass *modest_window_class;
194         gobject_class = (GObjectClass*) klass;
195         modest_window_class = (ModestWindowClass*) klass;
196
197         parent_class            = g_type_class_peek_parent (klass);
198         gobject_class->finalize = modest_msg_edit_window_finalize;
199
200         modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
201         modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
202         modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
203         modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
204         modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
205
206         g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
207 }
208
209 static void
210 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
211 {
212         ModestMsgEditWindowPrivate *priv;
213         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
214
215         priv->msg_body      = NULL;
216         priv->from_field    = NULL;
217         priv->to_field      = NULL;
218         priv->cc_field      = NULL;
219         priv->bcc_field     = NULL;
220         priv->subject_field = NULL;
221         priv->attachments   = NULL;
222         priv->last_cid      = 0;
223         priv->zoom_level    = 1.0;
224
225         priv->cc_caption    = NULL;
226         priv->bcc_caption    = NULL;
227
228         priv->priority_flags = 0;
229 }
230
231
232
233 static void
234 save_settings (ModestMsgEditWindow *self)
235 {
236         modest_widget_memory_save (modest_runtime_get_conf(),
237                                    G_OBJECT(self), "modest-edit-msg-window");
238 }
239
240
241 static void
242 restore_settings (ModestMsgEditWindow *self)
243 {
244         modest_widget_memory_restore (modest_runtime_get_conf(),
245                                       G_OBJECT(self), "modest-edit-msg-window");
246 }
247
248
249 /* FIXME: this is a dup from the one in gtk/ */
250 static ModestPairList*
251 get_transports (void)
252 {
253         ModestAccountMgr *account_mgr;
254         GSList *transports = NULL;
255         GSList *cursor, *accounts;
256         
257         account_mgr = modest_runtime_get_account_mgr();
258         cursor = accounts = modest_account_mgr_account_names (account_mgr); 
259         while (cursor) {
260                 gchar *account_name = (gchar*)cursor->data;
261                 gchar *from_string  = modest_account_mgr_get_from_string (account_mgr,
262                                                                           account_name);
263                 if (!from_string)  {
264                         /* something went wrong: ignore this one */
265                         g_free (account_name);
266                         cursor->data = NULL;
267                 } else {
268                         ModestPair *pair;
269                         pair = modest_pair_new ((gpointer) account_name,
270                                                 (gpointer) from_string , TRUE);
271                         transports = g_slist_prepend (transports, pair);
272                 } /* don't free account name; it's freed when the transports list is freed */
273                 cursor = cursor->next;
274         }
275         g_slist_free (accounts);
276         return transports;
277 }
278
279
280 static void
281 text_buffer_mark_set (GtkTextBuffer *buffer, GtkTextIter *iter, GtkTextMark *mark, gpointer userdata)
282 {
283         ModestMsgEditWindow *window;
284         ModestMsgEditWindowPrivate *priv;
285         GdkRectangle location;
286         gint v_scroll_min_value = 0;
287         gint v_scroll_max_value = 0;
288         gint v_scroll_visible;
289         GtkAdjustment *vadj;
290         GtkTextMark *insert_mark;
291         GtkTextIter insert_iter;
292         
293         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (userdata));
294         g_return_if_fail (GTK_IS_TEXT_MARK (mark));
295         window = MODEST_MSG_EDIT_WINDOW (userdata);
296         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
297                 
298         insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
299         gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &insert_iter, insert_mark);
300         gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &insert_iter, &location);
301         
302         if (priv->header_box)
303                 v_scroll_min_value += priv->header_box->allocation.height + DEFAULT_MAIN_VBOX_SPACING;
304         v_scroll_min_value += location.y;
305         v_scroll_max_value = v_scroll_min_value + location.height;
306         
307         v_scroll_visible = GTK_WIDGET (window)->allocation.height;
308         
309         vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll));
310         
311         if (((gdouble) v_scroll_min_value) < vadj->value)
312                 gtk_adjustment_set_value (vadj, v_scroll_min_value);
313         else if (((gdouble) v_scroll_max_value) > (vadj->value + vadj->page_size))
314                 gtk_adjustment_set_value (vadj, ((gdouble)v_scroll_max_value) - vadj->page_size);
315 }
316
317 static void
318 init_window (ModestMsgEditWindow *obj)
319 {
320         GtkWidget *from_caption, *to_caption, *subject_caption;
321         GtkWidget *main_vbox;
322         ModestMsgEditWindowPrivate *priv;
323         ModestPairList *protos;
324         GtkSizeGroup *size_group;
325         GtkWidget *frame;
326         GtkWidget *scroll_area;
327         GtkWidget *subject_box;
328         GtkWidget *attachment_icon;
329
330         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
331
332         size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
333
334         protos = get_transports ();
335         priv->from_field    = modest_combo_box_new (protos, g_str_equal);
336         modest_pair_list_free (protos);
337
338         priv->to_field      = modest_recpt_editor_new ();
339         priv->cc_field      = modest_recpt_editor_new ();
340         priv->bcc_field     = modest_recpt_editor_new ();
341         subject_box = gtk_hbox_new (FALSE, 0);
342         priv->priority_icon = gtk_image_new ();
343         gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
344         priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
345         g_object_set (G_OBJECT (priv->subject_field), "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
346         gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
347         priv->add_attachment_button = gtk_button_new ();
348         gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
349         gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
350         gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
351         attachment_icon = gtk_image_new_from_icon_name ("qgn_list_gene_attacpap", GTK_ICON_SIZE_BUTTON);
352         gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
353         gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
354         priv->attachments_view = modest_attachments_view_new (NULL);
355         
356         priv->header_box = gtk_vbox_new (FALSE, 0);
357         
358         from_caption = hildon_caption_new (size_group, _("From:"), priv->from_field, NULL, 0);
359         to_caption = hildon_caption_new (size_group, _("To:"), priv->to_field, NULL, 0);
360         priv->cc_caption = hildon_caption_new (size_group, _("Cc:"), priv->cc_field, NULL, 0);
361         priv->bcc_caption = hildon_caption_new (size_group, _("Bcc:"), priv->bcc_field, NULL, 0);
362         subject_caption = hildon_caption_new (size_group, _("Subject:"), subject_box, NULL, 0);
363         priv->attachments_caption = hildon_caption_new (size_group, _("Attachments:"), priv->attachments_view, NULL, 0);
364         g_object_unref (size_group);
365
366         size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
367         modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
368         modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
369         modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
370         gtk_size_group_add_widget (size_group, priv->subject_field);
371         gtk_size_group_add_widget (size_group, priv->attachments_view);
372         g_object_unref (size_group);
373
374         gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
375         gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
376         gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
377         gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
378         gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
379         gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
380         gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
381
382
383         priv->msg_body = wp_text_view_new ();
384         gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
385         priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
386         g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
387         wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
388 /*      gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
389         wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
390
391         g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
392                           G_CALLBACK (text_buffer_refresh_attributes), obj);
393         g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
394                           G_CALLBACK (text_buffer_mark_set), obj);
395         g_signal_connect (G_OBJECT (obj), "window-state-event",
396                           G_CALLBACK (modest_msg_edit_window_window_state_event),
397                           NULL);
398         g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook", 
399                                   G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
400
401         priv->scroll = gtk_scrolled_window_new (NULL, NULL);
402         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
403         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
404         
405         main_vbox = gtk_vbox_new  (FALSE, DEFAULT_MAIN_VBOX_SPACING);
406
407         gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
408         frame = gtk_frame_new (NULL);
409         gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
410
411         gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
412         gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
413         gtk_widget_show_all (GTK_WIDGET(priv->scroll));
414         
415         if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL))
416                 gtk_widget_hide (priv->cc_field);
417         if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL))
418                 gtk_widget_hide (priv->bcc_field);
419
420         gtk_container_add (GTK_CONTAINER(obj), priv->scroll);
421         scroll_area = hildon_scroll_area_new (priv->scroll, priv->msg_body);
422         gtk_container_add (GTK_CONTAINER (frame), scroll_area);
423         gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area), 
424                                              gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
425 }
426         
427
428
429 static void
430 modest_msg_edit_window_finalize (GObject *obj)
431 {
432         G_OBJECT_CLASS(parent_class)->finalize (obj);
433 }
434
435
436
437 static gboolean
438 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
439 {
440         save_settings (self);
441         return FALSE;
442 }
443
444 static GtkWidget *
445 menubar_to_menu (GtkUIManager *ui_manager)
446 {
447         GtkWidget *main_menu;
448         GtkWidget *menubar;
449         GList *iter;
450
451         /* Create new main menu */
452         main_menu = gtk_menu_new();
453
454         /* Get the menubar from the UI manager */
455         menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
456
457         iter = gtk_container_get_children (GTK_CONTAINER (menubar));
458         while (iter) {
459                 GtkWidget *menu;
460
461                 menu = GTK_WIDGET (iter->data);
462                 gtk_widget_reparent(menu, main_menu);
463
464                 iter = g_list_next (iter);
465         }
466         return main_menu;
467 }
468
469
470 static void
471 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
472 {
473         TnyHeader *header;
474         const gchar *to, *cc, *bcc, *subject, *body;
475         ModestMsgEditWindowPrivate *priv;
476         
477         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
478         g_return_if_fail (TNY_IS_MSG (msg));
479
480         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
481
482         header = tny_msg_get_header (msg);
483         to      = tny_header_get_to (header);
484         cc      = tny_header_get_cc (header);
485         bcc     = tny_header_get_bcc (header);
486         subject = tny_header_get_subject (header);
487
488         if (to)
489                 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field),  to);
490         if (cc)
491                 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field),  cc);
492         if (bcc)
493                 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
494         if (subject)
495                 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);   
496
497 /*      gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
498         wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
499         body = modest_tny_msg_get_body (msg, FALSE);
500         if ((body!=NULL) && (body[0] != '\0')) {
501                 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
502                 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
503                                                     (gchar *) body,
504                                                     -1);
505                 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
506         } else {
507                 WPTextBufferFormat fmt = {0};
508
509                 fmt.font_size = DEFAULT_FONT_SIZE;
510                 fmt.font = DEFAULT_FONT;
511                 fmt.rich_text = 1;
512                 fmt.text_position = TEXT_POSITION_NORMAL;
513                 fmt.justification = 0;
514                 fmt.cs.font_size = 1;
515                 fmt.cs.font = 1;
516                 fmt.cs.text_position = 1;
517                 fmt.cs.justification = 1;
518                 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &fmt);
519         }
520
521         /* Set the default focus depending on having already a To: field or not */
522         if ((!to)||(*to == '\0')) {
523                 gtk_widget_grab_focus (priv->to_field);
524         } else {
525                 gtk_widget_grab_focus (priv->msg_body);
526         }
527
528         /* TODO: lower priority, select in the From: combo to the
529            value that comes from msg <- not sure, should it be
530            allowed? */
531         
532         /* Add attachments to the view */
533         modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
534         if (priv->attachments == NULL)
535                 gtk_widget_hide_all (priv->attachments_caption);
536 }
537
538 static void
539 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
540                                 gpointer data)
541 {
542         GList *item_children, *node;
543         GtkWidget *bin_child;
544
545         bin_child = gtk_bin_get_child (GTK_BIN(item));
546
547         item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
548         
549         for (node = item_children; node != NULL; node = g_list_next (node)) {
550                 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
551                         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
552                 }
553         }
554         g_list_free (item_children);
555 }
556
557 static void
558 menu_tool_button_dont_expand (GtkMenuToolButton *item)
559 {
560         GtkWidget *box;
561         GList *item_children, *node;
562
563         box = gtk_bin_get_child (GTK_BIN (item));
564         gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
565         item_children = gtk_container_get_children (GTK_CONTAINER (box));
566         
567         for (node = item_children; node != NULL; node = g_list_next (node)) {
568                 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
569                 if (GTK_IS_TOGGLE_BUTTON (node->data))
570                         gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
571                 else if (GTK_IS_BUTTON (node->data))
572                         gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
573         }
574         g_list_free (item_children);
575 }
576
577
578 static void
579 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
580 {
581         ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
582         ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
583         GtkWidget *placeholder;
584         GtkWidget *tool_item;
585         gint insert_index;
586         gchar size_text[5];
587         gint size_index;
588         gint font_index;
589         GtkWidget *sizes_menu;
590         GtkWidget *fonts_menu;
591         GSList *radio_group = NULL;
592         gchar *markup;
593
594         /* Toolbar */
595         parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
596         hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
597
598         /* should we hide the toolbar? */
599         if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
600                 gtk_widget_hide (parent_priv->toolbar);
601
602         /* Font color placeholder */
603         placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
604         insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
605
606         /* font color */
607         tool_item = GTK_WIDGET (gtk_tool_item_new ());
608         priv->font_color_button = hildon_color_button_new ();
609         gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
610         gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
611         gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
612         gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
613         g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
614
615         /* Font size and face placeholder */
616         placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
617         insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
618         /* font_size */
619         tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
620         priv->size_tool_button_label = gtk_label_new (NULL);
621         snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
622         markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
623                               size_text,"</span>", NULL);
624         gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
625         g_free (markup);
626         gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
627         sizes_menu = gtk_menu_new ();
628         priv->size_items_group = NULL;
629         radio_group = NULL;
630         for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
631                 GtkWidget *size_menu_item;
632
633                 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
634                 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
635                 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
636                 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
637                 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
638                 gtk_widget_show (size_menu_item);
639
640                 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
641                         
642                 g_signal_connect (G_OBJECT (size_menu_item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
643                                   window);
644         }
645         priv->size_items_group = g_slist_reverse (priv->size_items_group);
646         gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
647         g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
648         gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
649         gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
650         gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
651         menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
652
653         /* font face */
654         tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
655         priv->font_tool_button_label = gtk_label_new (NULL);
656         markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
657         gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
658         g_free(markup);
659         gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
660         fonts_menu = gtk_menu_new ();
661         priv->font_items_group = NULL;
662         radio_group = NULL;
663         for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
664                 GtkWidget *font_menu_item;
665                 GtkWidget *child_label;
666
667                 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
668                 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
669                 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>", 
670                                       wp_get_font_name (font_index), "</span>", NULL);
671                 gtk_label_set_markup (GTK_LABEL (child_label), markup);
672                 g_free (markup);
673                 
674                 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
675                 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
676                 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
677                 gtk_widget_show (font_menu_item);
678
679                 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
680                         
681                 g_signal_connect (G_OBJECT (font_menu_item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
682                                   window);
683         }
684         priv->font_items_group = g_slist_reverse (priv->font_items_group);
685         gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
686         g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
687         gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
688         gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
689         gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
690         menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
691
692         /* Set expand and homogeneous for remaining items */
693         tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsSend");
694         gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
695         gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
696         tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
697         gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
698         gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
699         tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
700         gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
701         gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
702
703
704 }
705
706
707
708 ModestWindow*
709 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
710 {
711         GObject *obj;
712         ModestWindowPrivate *parent_priv;
713         ModestMsgEditWindowPrivate *priv;
714         GtkActionGroup *action_group;
715         GError *error = NULL;
716         GdkPixbuf *window_icon = NULL;
717
718         g_return_val_if_fail (msg, NULL);
719         
720         obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
721
722         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
723         parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
724
725         parent_priv->ui_manager = gtk_ui_manager_new();
726         action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
727
728         /* Add common actions */
729         gtk_action_group_add_actions (action_group,
730                                       modest_msg_edit_action_entries,
731                                       G_N_ELEMENTS (modest_msg_edit_action_entries),
732                                       obj);
733         gtk_action_group_add_toggle_actions (action_group,
734                                              modest_msg_edit_toggle_action_entries,
735                                              G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
736                                              obj);
737         gtk_action_group_add_radio_actions (action_group,
738                                             modest_msg_edit_alignment_radio_action_entries,
739                                             G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
740                                             GTK_JUSTIFY_LEFT,
741                                             G_CALLBACK (modest_ui_actions_on_change_justify),
742                                             obj);
743         gtk_action_group_add_radio_actions (action_group,
744                                             modest_msg_edit_zoom_action_entries,
745                                             G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
746                                             100,
747                                             G_CALLBACK (modest_ui_actions_on_change_zoom),
748                                             obj);
749         gtk_action_group_add_radio_actions (action_group,
750                                             modest_msg_edit_priority_action_entries,
751                                             G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
752                                             0,
753                                             G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
754                                             obj);
755         gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
756         g_object_unref (action_group);
757
758         /* Load the UI definition */
759         gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml", &error);
760         if (error != NULL) {
761                 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
762                 g_error_free (error);
763                 error = NULL;
764         }
765
766         /* Add accelerators */
767         gtk_window_add_accel_group (GTK_WINDOW (obj), 
768                                     gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
769
770         /* Menubar */
771         parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
772         hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
773
774         /* Init window */
775         init_window (MODEST_MSG_EDIT_WINDOW(obj));
776
777         restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
778                 
779         gtk_window_set_title (GTK_WINDOW(obj), "Modest");
780         gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
781
782         g_signal_connect (G_OBJECT(obj), "delete-event",
783                           G_CALLBACK(on_delete_event), obj);
784
785         modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
786
787         modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
788
789         set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
790
791         text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
792
793         /* Set window icon */
794         window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
795         gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
796         
797         return (ModestWindow*)obj;
798 }
799
800 static gint
801 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
802 {
803         GString **string_buffer = (GString **) user_data;
804
805         *string_buffer = g_string_append (*string_buffer, buffer);
806    
807         return 0;
808 }
809
810 static gchar *
811 get_formatted_data (ModestMsgEditWindow *edit_window)
812 {
813         ModestMsgEditWindowPrivate *priv;
814         GString *string_buffer = g_string_new ("");
815         
816         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
817
818         wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
819
820         return g_string_free (string_buffer, FALSE);
821                                                                         
822 }
823
824 MsgData * 
825 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
826 {
827         MsgData *data;
828         const gchar *account_name;
829         GtkTextBuffer *buf;
830         GtkTextIter b, e;
831         ModestMsgEditWindowPrivate *priv;
832         
833         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
834
835         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
836                                                                         
837         account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
838         g_return_val_if_fail (account_name, NULL);
839         
840         buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));        
841         gtk_text_buffer_get_bounds (buf, &b, &e);
842         
843         /* don't free these (except from) */
844         data = g_slice_new0 (MsgData);
845         data->from    =  modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
846                                                              account_name);
847         data->to      =  (gchar*) modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR(priv->to_field));
848         data->cc      =  (gchar*) modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR(priv->cc_field));
849         data->bcc     =  (gchar*) modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR(priv->bcc_field));
850         data->subject =  (gchar*) gtk_entry_get_text (GTK_ENTRY(priv->subject_field));  
851         data->plain_body =  (gchar *) gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE);
852         data->html_body  =  get_formatted_data (edit_window);
853         data->attachments = priv->attachments;
854         data->priority_flags = priv->priority_flags;
855
856         return data;
857 }
858
859 void 
860 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
861                                                       MsgData *data)
862 {
863         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
864
865         g_free (data->from);
866         g_free (data->html_body);
867         g_free (data->plain_body);
868         g_slice_free (MsgData, data);
869 }
870
871 ModestMsgEditFormat
872 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
873 {
874         gboolean rich_text;
875         ModestMsgEditWindowPrivate *priv = NULL;
876         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
877
878         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
879
880         rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
881         if (rich_text)
882                 return MODEST_MSG_EDIT_FORMAT_HTML;
883         else
884                 return MODEST_MSG_EDIT_FORMAT_TEXT;
885 }
886
887 void
888 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
889                                    ModestMsgEditFormat format)
890 {
891         ModestMsgEditWindowPrivate *priv;
892
893         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
894         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
895
896         switch (format) {
897         case MODEST_MSG_EDIT_FORMAT_HTML:
898                 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
899                 break;
900         case MODEST_MSG_EDIT_FORMAT_TEXT:
901                 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
902                 break;
903         default:
904                 g_return_if_reached ();
905         }
906 }
907
908 ModestMsgEditFormatState *
909 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
910 {
911         ModestMsgEditFormatState *format_state = NULL;
912         ModestMsgEditWindowPrivate *priv;
913         WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
914
915         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
916         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
917
918         wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
919
920         format_state = g_new0 (ModestMsgEditFormatState, 1);
921         format_state->bold = buffer_format->bold&0x1;
922         format_state->italics = buffer_format->italic&0x1;
923         format_state->bullet = buffer_format->bullet&0x1;
924         format_state->color = buffer_format->color;
925         format_state->font_size = buffer_format->font_size;
926         format_state->font_family = wp_get_font_name (buffer_format->font);
927         format_state->justification = buffer_format->justification;
928         g_free (buffer_format);
929
930         return format_state;
931  
932 }
933
934 void
935 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
936                                          const ModestMsgEditFormatState *format_state)
937 {
938         ModestMsgEditWindowPrivate *priv;
939         WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
940         WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
941         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
942         g_return_if_fail (format_state != NULL);
943
944         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
945         gtk_widget_grab_focus (priv->msg_body);
946         buffer_format->bold = (format_state->bold != FALSE);
947         buffer_format->italic = (format_state->italics != FALSE);
948         buffer_format->color = format_state->color;
949         buffer_format->font_size = format_state->font_size;
950         buffer_format->font = wp_get_font_index (format_state->font_family, 0);
951         buffer_format->justification = format_state->justification;
952         buffer_format->bullet = format_state->bullet;
953
954         wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
955
956         buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
957         buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
958         buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
959         buffer_format->cs.font_size =  (buffer_format->font_size != current_format->font_size);
960         buffer_format->cs.font = (buffer_format->font != current_format->font);
961         buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
962         buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
963
964         wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
965         if (buffer_format->cs.bold) {
966                 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
967         }
968         if (buffer_format->cs.italic) {
969                 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
970         }
971         if (buffer_format->cs.color) {
972                 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
973         }
974         if (buffer_format->cs.font_size) {
975                 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
976         }
977         if (buffer_format->cs.justification) {
978                 switch (buffer_format->justification) {
979                 case GTK_JUSTIFY_LEFT:
980                         wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
981                         break;
982                 case GTK_JUSTIFY_CENTER:
983                         wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
984                         break;
985                 case GTK_JUSTIFY_RIGHT:
986                         wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
987                         break;
988                 default:
989                         break;
990                 }
991                         
992         }
993         if (buffer_format->cs.font) {
994                 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
995         }
996         if (buffer_format->cs.bullet) {
997                 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
998         }
999 /*      wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1000         wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1001
1002         g_free (current_format);
1003
1004 }
1005
1006 static void
1007 toggle_action_set_active_block_notify (GtkToggleAction *action,
1008                                        gboolean value)
1009 {
1010         GSList *proxies = NULL;
1011
1012         for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1013              proxies != NULL; proxies = g_slist_next (proxies)) {
1014                 GtkWidget *widget = (GtkWidget *) proxies->data;
1015                 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1016         }
1017
1018         gtk_toggle_action_set_active (action, value);
1019
1020         for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1021              proxies != NULL; proxies = g_slist_next (proxies)) {
1022                 GtkWidget *widget = (GtkWidget *) proxies->data;
1023                 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1024         }
1025 }
1026
1027 static void
1028 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1029 {
1030         WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1031         GtkAction *action;
1032         ModestWindowPrivate *parent_priv;
1033         ModestMsgEditWindowPrivate *priv;
1034         GtkWidget *new_size_menuitem;
1035         GtkWidget *new_font_menuitem;
1036         
1037         parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1038         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1039
1040         wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1041         
1042         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1043         toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1044
1045         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1046         toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1047
1048         action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1049         toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1050
1051         g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button), 
1052                                          G_CALLBACK (modest_msg_edit_window_color_button_change),
1053                                          window);
1054         hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1055         g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button), 
1056                                            G_CALLBACK (modest_msg_edit_window_color_button_change),
1057                                            window);
1058
1059         new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group, 
1060                                                       buffer_format->font_size))->data);
1061         if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1062                 GtkWidget *label;
1063                 gchar *markup;
1064
1065                 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1066                 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1067                 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1068                 g_free (markup);
1069                 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1070                                                  G_CALLBACK (modest_msg_edit_window_size_change),
1071                                                  window);
1072                 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1073                 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1074                                                    G_CALLBACK (modest_msg_edit_window_size_change),
1075                                                    window);
1076         }
1077
1078         new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group, 
1079                                                       buffer_format->font))->data);
1080         if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1081                 GtkWidget *label;
1082                 gchar *markup;
1083
1084                 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1085                 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1086                 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1087                 g_free (markup);
1088                 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1089                                                  G_CALLBACK (modest_msg_edit_window_font_change),
1090                                                  window);
1091                 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1092                 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1093                                                    G_CALLBACK (modest_msg_edit_window_font_change),
1094                                                    window);
1095         }
1096
1097         g_free (buffer_format);
1098
1099 }
1100
1101 void
1102 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1103 {
1104         
1105         WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1106         ModestMsgEditWindowPrivate *priv;
1107         GtkWidget *dialog = NULL;
1108         gint response;
1109         const GdkColor *new_color = NULL;
1110         
1111         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1112         wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1113         
1114         dialog = hildon_color_selector_new (GTK_WINDOW (window));
1115         hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), & (buffer_format->color));
1116         g_free (buffer_format);
1117
1118         response = gtk_dialog_run (GTK_DIALOG (dialog));
1119         switch (response) {
1120         case GTK_RESPONSE_OK:
1121                 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1122                 break;
1123         default:
1124                 break;
1125         }
1126         gtk_widget_destroy (dialog);
1127
1128         if (new_color != NULL)
1129                 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1130
1131 }
1132
1133 void
1134 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1135 {
1136         
1137         ModestMsgEditWindowPrivate *priv;
1138         GtkWidget *dialog = NULL;
1139         gint response;
1140         const GdkColor *old_color = NULL;
1141         const GdkColor *new_color = NULL;
1142         
1143         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1144         old_color = wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1145         
1146         dialog = hildon_color_selector_new (GTK_WINDOW (window));
1147         hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), (GdkColor *) old_color);
1148
1149         response = gtk_dialog_run (GTK_DIALOG (dialog));
1150         switch (response) {
1151         case GTK_RESPONSE_OK:
1152                 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1153                 break;
1154         default:
1155                 break;
1156         }
1157         gtk_widget_destroy (dialog);
1158
1159         if (new_color != NULL)
1160                 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1161
1162 }
1163
1164 void
1165 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1166 {
1167         
1168         ModestMsgEditWindowPrivate *priv;
1169         GtkWidget *dialog = NULL;
1170         gint response = 0;
1171         gchar *filename = NULL;
1172         
1173         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1174         
1175         dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1176
1177         response = gtk_dialog_run (GTK_DIALOG (dialog));
1178         switch (response) {
1179         case GTK_RESPONSE_OK:
1180                 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1181                 break;
1182         default:
1183                 break;
1184         }
1185         gtk_widget_destroy (dialog);
1186
1187         if (filename) {
1188                 GdkPixbuf *pixbuf = NULL;
1189                 GtkTextIter position;
1190                 GtkTextMark *insert_mark;
1191
1192                 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1193                 if (pixbuf) {
1194                         gint image_file_id;
1195                         GdkPixbufFormat *pixbuf_format;
1196
1197                         image_file_id = g_open (filename, O_RDONLY, 0);
1198                         pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1199                         if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1200                                 TnyMimePart *image_part;
1201                                 TnyStream *image_stream;
1202                                 gchar **mime_types;
1203                                 gchar *mime_type;
1204                                 gchar *basename;
1205                                 gchar *content_id;
1206
1207                                 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1208                                 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1209                                         mime_type = mime_types[0];
1210                                 } else {
1211                                         mime_type = "image/unknown";
1212                                 }
1213                                 image_part = tny_platform_factory_new_mime_part
1214                                         (modest_runtime_get_platform_factory ());
1215                                 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1216
1217                                 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1218                                 g_strfreev (mime_types);
1219
1220                                 content_id = g_strdup_printf ("%d", priv->last_cid);
1221                                 tny_mime_part_set_content_id (image_part, content_id);
1222                                 g_free (content_id);
1223                                 priv->last_cid++;
1224
1225                                 basename = g_path_get_basename (filename);
1226                                 tny_mime_part_set_filename (image_part, basename);
1227                                 g_free (basename);
1228                                 
1229                                 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1230                                 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1231                                 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1232                                 priv->attachments = g_list_prepend (priv->attachments, image_part);
1233                                 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1234                                                                         image_part);
1235                                 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1236                                 gtk_widget_show_all (priv->attachments_caption);
1237                         } else if (image_file_id == -1) {
1238                                 close (image_file_id);
1239                         }
1240                 }
1241         }
1242
1243
1244 }
1245
1246 static void
1247 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1248                                             gpointer userdata)
1249 {
1250         ModestMsgEditWindowPrivate *priv;
1251         GdkColor *new_color;
1252
1253         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1254         new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1255
1256         wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1257         gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1258
1259 }
1260
1261 static void
1262 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1263                                     gpointer userdata)
1264 {
1265         ModestMsgEditWindowPrivate *priv;
1266         gint new_size_index;
1267         ModestMsgEditWindow *window;
1268         GtkWidget *label;
1269         
1270         window = MODEST_MSG_EDIT_WINDOW (userdata);
1271         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1272         gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1273
1274         if (gtk_check_menu_item_get_active (menu_item)) {
1275                 gchar *markup;
1276
1277                 label = gtk_bin_get_child (GTK_BIN (menu_item));
1278                 
1279                 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1280
1281                 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, 
1282                                                    (gpointer) wp_get_font_size_index (new_size_index, 12)))
1283                         wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1284                 
1285                 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1286                 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1287                 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1288                 g_free (markup);
1289         }
1290 }
1291
1292 static void
1293 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1294                                     gpointer userdata)
1295 {
1296         ModestMsgEditWindowPrivate *priv;
1297         gint new_font_index;
1298         ModestMsgEditWindow *window;
1299         GtkWidget *label;
1300         
1301         window = MODEST_MSG_EDIT_WINDOW (userdata);
1302         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1303         gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1304
1305         if (gtk_check_menu_item_get_active (menu_item)) {
1306                 gchar *markup;
1307
1308                 label = gtk_bin_get_child (GTK_BIN (menu_item));
1309                 
1310                 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1311
1312                 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, 
1313                                                    (gpointer) new_font_index))
1314                         wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1315                 
1316                 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1317                     markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1318                 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1319                 g_free (markup);
1320         }
1321 }
1322
1323 static void
1324 modest_msg_edit_window_set_zoom (ModestWindow *window,
1325                                  gdouble zoom)
1326 {
1327         ModestMsgEditWindowPrivate *priv;
1328      
1329         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1330
1331         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1332         priv->zoom_level = zoom;
1333         wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1334 }
1335
1336 static gdouble
1337 modest_msg_edit_window_get_zoom (ModestWindow *window)
1338 {
1339         ModestMsgEditWindowPrivate *priv;
1340      
1341         g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1342
1343         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1344         return priv->zoom_level;
1345 }
1346
1347 static gboolean
1348 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1349 {
1350         ModestWindowPrivate *parent_priv;
1351         GtkRadioAction *zoom_radio_action;
1352         GSList *group, *node;
1353
1354         parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1355         zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, 
1356                                                                          "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1357
1358         group = gtk_radio_action_get_group (zoom_radio_action);
1359
1360         if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1361                 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1362                 return FALSE;
1363         }
1364
1365         for (node = group; node != NULL; node = g_slist_next (node)) {
1366                 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1367                         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1368                         return TRUE;
1369                 }
1370         }
1371         return FALSE;
1372 }
1373
1374 static gboolean
1375 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1376 {
1377         ModestWindowPrivate *parent_priv;
1378         GtkRadioAction *zoom_radio_action;
1379         GSList *group, *node;
1380
1381         parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1382         zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, 
1383                                                                          "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1384
1385         group = gtk_radio_action_get_group (zoom_radio_action);
1386
1387         for (node = group; node != NULL; node = g_slist_next (node)) {
1388                 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1389                         if (node->next != NULL) {
1390                                 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1391                                 return TRUE;
1392                         } else
1393                                 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1394                         break;
1395                 }
1396         }
1397         return FALSE;
1398 }
1399
1400 static gboolean
1401 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1402 {
1403         if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1404                 ModestWindowPrivate *parent_priv;
1405                 ModestWindowMgr *mgr;
1406                 gboolean is_fullscreen;
1407                 GtkAction *fs_toggle_action;
1408                 gboolean active;
1409
1410                 mgr = modest_runtime_get_window_mgr ();
1411                 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1412
1413                 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1414                 
1415                 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1416                 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1417                 if (is_fullscreen != active)
1418                         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1419         }
1420
1421         return FALSE;
1422
1423 }
1424
1425 void
1426 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1427 {
1428         ModestWindowPrivate *parent_priv;
1429         GtkAction *fs_toggle_action;
1430         gboolean active;
1431
1432         parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1433
1434         fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1435         active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1436         gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1437 }
1438
1439 void
1440 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window, 
1441                                 gboolean show)
1442 {
1443         ModestMsgEditWindowPrivate *priv = NULL;
1444         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1445
1446         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1447         if (show)
1448                 gtk_widget_show (priv->cc_caption);
1449         else
1450                 gtk_widget_hide (priv->cc_caption);
1451 }
1452
1453 void
1454 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window, 
1455                                  gboolean show)
1456 {
1457         ModestMsgEditWindowPrivate *priv = NULL;
1458         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1459
1460         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1461         if (show)
1462                 gtk_widget_show (priv->bcc_caption);
1463         else
1464                 gtk_widget_hide (priv->bcc_caption);
1465 }
1466
1467 static void
1468 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1469                                          ModestRecptEditor *editor)
1470 {
1471         ModestMsgEditWindowPrivate *priv;
1472
1473         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1474         g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1475         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1476
1477         if (editor == NULL) {
1478                 GtkWidget *view_focus;
1479                 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1480
1481                 if (gtk_widget_get_parent (view_focus) && 
1482                     MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (view_focus))) {
1483                         editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (view_focus));
1484                 } else {
1485                         editor = MODEST_RECPT_EDITOR (priv->to_field);
1486                 }
1487         }
1488
1489         modest_address_book_select_addresses (editor);
1490
1491 }
1492 static void
1493 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1494                                      gboolean show_toolbar)
1495 {
1496         ModestWindowPrivate *parent_priv;
1497         
1498         parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1499
1500         /* FIXME: we can not just use the code of
1501            modest_msg_edit_window_setup_toolbar because it has a
1502            mixture of both initialization and creation code. */
1503
1504         if (show_toolbar)
1505                 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1506         else
1507                 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1508 }
1509
1510 void
1511 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1512                                            TnyHeaderFlags priority_flags)
1513 {
1514         ModestMsgEditWindowPrivate *priv;
1515
1516         g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1517
1518         priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1519         priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1520
1521         if (priv->priority_flags != priority_flags) {
1522
1523                 priv->priority_flags = priority_flags;
1524
1525                 switch (priority_flags) {
1526                 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1527                         gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1528                         gtk_widget_show (priv->priority_icon);
1529                         break;
1530                 case TNY_HEADER_FLAG_LOW_PRIORITY:
1531                         gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1532                         gtk_widget_show (priv->priority_icon);
1533                         break;
1534                 default:
1535                         gtk_widget_hide (priv->priority_icon);
1536                         break;
1537                 }
1538         }
1539 }