1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
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.
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.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
40 #include <modest-account-mgr.h>
41 #include <modest-account-mgr-helpers.h>
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>
48 #include <modest-runtime.h>
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 "modest-text-utils.h"
59 #include <tny-simple-list.h>
60 #include <wptextview.h>
61 #include <wptextbuffer.h>
62 #include "modest-scroll-area.h"
64 #include "modest-hildon-includes.h"
65 #include "widgets/modest-msg-edit-window-ui.h"
68 #define DEFAULT_FONT_SIZE 3
69 #define DEFAULT_FONT 2
70 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
71 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
72 #define DEFAULT_MAIN_VBOX_SPACING 6
73 #define SUBJECT_MAX_LENGTH 1000
75 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
76 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
77 static void modest_msg_edit_window_finalize (GObject *obj);
79 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
80 static void to_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
81 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
82 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
83 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
84 static void reset_modified (ModestMsgEditWindow *editor);
85 static gboolean is_modified (ModestMsgEditWindow *editor);
87 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
88 static void text_buffer_mark_set (GtkTextBuffer *buffer, GtkTextIter *location, GtkTextMark *mark, gpointer userdata);
89 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
90 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
92 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
94 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
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,
100 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
101 ModestRecptEditor *editor);
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 static void update_dimmed (ModestMsgEditWindow *window);
113 /* list my signals */
120 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
121 struct _ModestMsgEditWindowPrivate {
123 GtkWidget *header_box;
124 GtkWidget *from_field;
127 GtkWidget *bcc_field;
128 GtkWidget *subject_field;
129 GtkWidget *attachments_view;
130 GtkWidget *priority_icon;
131 GtkWidget *add_attachment_button;
133 GtkWidget *cc_caption;
134 GtkWidget *bcc_caption;
135 GtkWidget *attachments_caption;
137 GtkTextBuffer *text_buffer;
139 GtkWidget *font_size_toolitem;
140 GtkWidget *font_face_toolitem;
141 GtkWidget *font_color_button;
142 GSList *font_items_group;
143 GtkWidget *font_tool_button_label;
144 GSList *size_items_group;
145 GtkWidget *size_tool_button_label;
152 TnyHeaderFlags priority_flags;
159 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
160 MODEST_TYPE_MSG_EDIT_WINDOW, \
161 ModestMsgEditWindowPrivate))
163 static GtkWindowClass *parent_class = NULL;
165 /* uncomment the following if you have defined any signals */
166 /* static guint signals[LAST_SIGNAL] = {0}; */
169 modest_msg_edit_window_get_type (void)
171 static GType my_type = 0;
173 static const GTypeInfo my_info = {
174 sizeof(ModestMsgEditWindowClass),
175 NULL, /* base init */
176 NULL, /* base finalize */
177 (GClassInitFunc) modest_msg_edit_window_class_init,
178 NULL, /* class finalize */
179 NULL, /* class data */
180 sizeof(ModestMsgEditWindow),
182 (GInstanceInitFunc) modest_msg_edit_window_init,
185 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
186 "ModestMsgEditWindow",
189 wp_text_buffer_library_init ();
195 save_state (ModestWindow *self)
197 modest_widget_memory_save (modest_runtime_get_conf(),
198 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
203 restore_settings (ModestMsgEditWindow *self)
205 modest_widget_memory_restore (modest_runtime_get_conf(),
206 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
211 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
213 GObjectClass *gobject_class;
214 ModestWindowClass *modest_window_class;
215 gobject_class = (GObjectClass*) klass;
216 modest_window_class = (ModestWindowClass*) klass;
218 parent_class = g_type_class_peek_parent (klass);
219 gobject_class->finalize = modest_msg_edit_window_finalize;
221 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
222 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
223 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
224 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
225 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
227 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
229 modest_window_class->save_state_func = save_state;
233 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
235 ModestMsgEditWindowPrivate *priv;
236 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
238 priv->msg_body = NULL;
239 priv->from_field = NULL;
240 priv->to_field = NULL;
241 priv->cc_field = NULL;
242 priv->bcc_field = NULL;
243 priv->subject_field = NULL;
244 priv->attachments = NULL;
246 priv->zoom_level = 1.0;
248 priv->cc_caption = NULL;
249 priv->bcc_caption = NULL;
251 priv->priority_flags = 0;
253 priv->draft_msg = NULL;
257 /* FIXME: this is a dup from the one in gtk/ */
258 static ModestPairList*
259 get_transports (void)
261 ModestAccountMgr *account_mgr;
262 GSList *transports = NULL;
263 GSList *cursor, *accounts;
265 account_mgr = modest_runtime_get_account_mgr();
266 cursor = accounts = modest_account_mgr_account_names (account_mgr,
267 TRUE /* only enabled accounts. */);
269 gchar *account_name = (gchar*)cursor->data;
270 gchar *from_string = modest_account_mgr_get_from_string (account_mgr,
273 /* something went wrong: ignore this one */
274 g_free (account_name);
278 pair = modest_pair_new ((gpointer) account_name,
279 (gpointer) from_string , TRUE);
280 transports = g_slist_prepend (transports, pair);
281 } /* don't free account name; it's freed when the transports list is freed */
282 cursor = cursor->next;
284 g_slist_free (accounts);
290 text_buffer_mark_set (GtkTextBuffer *buffer, GtkTextIter *iter, GtkTextMark *mark, gpointer userdata)
292 ModestMsgEditWindow *window;
293 ModestMsgEditWindowPrivate *priv;
294 GdkRectangle location;
295 gint v_scroll_min_value = 0;
296 gint v_scroll_max_value = 0;
297 gint v_scroll_visible;
299 GtkTextMark *insert_mark;
300 GtkTextIter insert_iter;
302 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (userdata));
303 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
304 window = MODEST_MSG_EDIT_WINDOW (userdata);
305 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
307 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
308 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &insert_iter, insert_mark);
309 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &insert_iter, &location);
311 if (priv->header_box)
312 v_scroll_min_value += priv->header_box->allocation.height + DEFAULT_MAIN_VBOX_SPACING;
313 v_scroll_min_value += location.y;
314 v_scroll_max_value = v_scroll_min_value + location.height;
316 v_scroll_visible = GTK_WIDGET (window)->allocation.height;
318 vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll));
320 if (((gdouble) v_scroll_min_value) < vadj->value)
321 gtk_adjustment_set_value (vadj, v_scroll_min_value);
322 else if (((gdouble) v_scroll_max_value) > (vadj->value + vadj->page_size))
323 gtk_adjustment_set_value (vadj, ((gdouble)v_scroll_max_value) - vadj->page_size);
327 init_window (ModestMsgEditWindow *obj)
329 GtkWidget *from_caption, *to_caption, *subject_caption;
330 GtkWidget *main_vbox;
331 ModestMsgEditWindowPrivate *priv;
332 ModestPairList *protos;
333 GtkSizeGroup *size_group;
335 GtkWidget *scroll_area;
336 GtkWidget *subject_box;
337 GtkWidget *attachment_icon;
339 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
341 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
343 protos = get_transports ();
344 priv->from_field = modest_combo_box_new (protos, g_str_equal);
345 modest_pair_list_free (protos);
347 priv->to_field = modest_recpt_editor_new ();
348 priv->cc_field = modest_recpt_editor_new ();
349 priv->bcc_field = modest_recpt_editor_new ();
350 subject_box = gtk_hbox_new (FALSE, 0);
351 priv->priority_icon = gtk_image_new ();
352 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
353 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
354 g_object_set (G_OBJECT (priv->subject_field), "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
355 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
356 priv->add_attachment_button = gtk_button_new ();
357 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
358 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
359 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
360 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
361 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
362 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
363 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
364 priv->attachments_view = modest_attachments_view_new (NULL);
366 priv->header_box = gtk_vbox_new (FALSE, 0);
368 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
369 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
370 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
371 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
372 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
373 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
374 g_object_unref (size_group);
376 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
377 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
378 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
379 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
380 gtk_size_group_add_widget (size_group, priv->subject_field);
381 gtk_size_group_add_widget (size_group, priv->attachments_view);
382 g_object_unref (size_group);
384 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
385 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
386 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
387 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
388 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
389 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
390 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
393 priv->msg_body = wp_text_view_new ();
394 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
395 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
396 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
397 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
398 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
399 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
401 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
402 G_CALLBACK (text_buffer_refresh_attributes), obj);
403 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
404 G_CALLBACK (text_buffer_mark_set), obj);
405 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
406 G_CALLBACK (text_buffer_can_undo), obj);
407 g_signal_connect (G_OBJECT (obj), "window-state-event",
408 G_CALLBACK (modest_msg_edit_window_window_state_event),
410 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
411 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
412 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
413 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
414 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
415 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
417 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
418 G_CALLBACK (msg_body_focus), obj);
419 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
420 G_CALLBACK (msg_body_focus), obj);
421 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
422 "changed", G_CALLBACK (to_field_changed), obj);
423 to_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
425 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
426 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
427 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
429 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
431 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
432 frame = gtk_frame_new (NULL);
433 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
435 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
436 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
437 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
439 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL))
440 gtk_widget_hide (priv->cc_field);
441 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL))
442 gtk_widget_hide (priv->bcc_field);
444 gtk_container_add (GTK_CONTAINER(obj), priv->scroll);
445 scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
446 gtk_container_add (GTK_CONTAINER (frame), scroll_area);
447 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
448 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
454 modest_msg_edit_window_finalize (GObject *obj)
456 G_OBJECT_CLASS(parent_class)->finalize (obj);
460 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
462 GtkWidget *close_dialog;
463 ModestMsgEditWindowPrivate *priv;
466 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
467 modest_window_save_state (MODEST_WINDOW (self));
468 if (is_modified (self)) {
469 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
470 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
471 gtk_widget_destroy (close_dialog);
473 if (response != GTK_RESPONSE_CANCEL) {
474 modest_ui_actions_on_save_to_drafts (NULL, self);
477 /* /\* remove old message from drafts *\/ */
478 /* if (priv->draft_msg) { */
479 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
480 /* TnyAccount *account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(), */
482 /* TNY_ACCOUNT_TYPE_STORE); */
483 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
484 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
485 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
486 /* tny_folder_remove_msg (folder, header, NULL); */
487 /* g_object_unref (folder); */
488 /* g_object_unref (header); */
489 /* g_object_unref (priv->draft_msg); */
490 /* priv->draft_msg = NULL; */
492 gtk_widget_destroy (GTK_WIDGET (self));
498 menubar_to_menu (GtkUIManager *ui_manager)
500 GtkWidget *main_menu;
504 /* Create new main menu */
505 main_menu = gtk_menu_new();
507 /* Get the menubar from the UI manager */
508 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
510 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
514 menu = GTK_WIDGET (iter->data);
515 gtk_widget_reparent(menu, main_menu);
517 iter = g_list_next (iter);
524 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
527 const gchar *to, *cc, *bcc, *subject;
529 ModestMsgEditWindowPrivate *priv;
532 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
533 g_return_if_fail (TNY_IS_MSG (msg));
535 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
537 header = tny_msg_get_header (msg);
538 to = tny_header_get_to (header);
539 cc = tny_header_get_cc (header);
540 bcc = tny_header_get_bcc (header);
541 subject = tny_header_get_subject (header);
544 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
546 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
548 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
550 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
552 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
553 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
554 body = modest_tny_msg_get_body (msg, FALSE);
556 if ((body == NULL)||(body[0] == '\0')) {
558 body = modest_text_utils_convert_to_html ("");
560 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
561 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
564 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
567 /* Get the default format required from configuration */
568 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
569 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
572 /* Set the default focus depending on having already a To: field or not */
573 if ((!to)||(*to == '\0')) {
574 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
576 gtk_widget_grab_focus (priv->msg_body);
579 /* TODO: lower priority, select in the From: combo to the
580 value that comes from msg <- not sure, should it be
583 /* Add attachments to the view */
584 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
585 if (priv->attachments == NULL)
586 gtk_widget_hide_all (priv->attachments_caption);
588 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
589 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
591 reset_modified (self);
593 update_dimmed (self);
594 text_buffer_can_undo (priv->text_buffer, FALSE, self);
596 priv->draft_msg = msg;
600 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
603 GList *item_children, *node;
604 GtkWidget *bin_child;
606 bin_child = gtk_bin_get_child (GTK_BIN(item));
608 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
610 for (node = item_children; node != NULL; node = g_list_next (node)) {
611 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
612 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
615 g_list_free (item_children);
619 menu_tool_button_dont_expand (GtkMenuToolButton *item)
622 GList *item_children, *node;
624 box = gtk_bin_get_child (GTK_BIN (item));
625 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
626 item_children = gtk_container_get_children (GTK_CONTAINER (box));
628 for (node = item_children; node != NULL; node = g_list_next (node)) {
629 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
630 if (GTK_IS_TOGGLE_BUTTON (node->data))
631 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
632 else if (GTK_IS_BUTTON (node->data))
633 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
635 g_list_free (item_children);
640 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
642 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
643 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
644 GtkWidget *placeholder;
645 GtkWidget *tool_item;
650 GtkWidget *sizes_menu;
651 GtkWidget *fonts_menu;
652 GSList *radio_group = NULL;
656 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
657 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
659 /* should we hide the toolbar? */
660 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
661 gtk_widget_hide (parent_priv->toolbar);
663 /* Font color placeholder */
664 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
665 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
668 tool_item = GTK_WIDGET (gtk_tool_item_new ());
669 priv->font_color_button = hildon_color_button_new ();
670 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
671 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
672 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
673 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
674 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
676 /* Font size and face placeholder */
677 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
678 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
680 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
681 priv->size_tool_button_label = gtk_label_new (NULL);
682 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
683 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
684 size_text,"</span>", NULL);
685 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
687 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
688 sizes_menu = gtk_menu_new ();
689 priv->size_items_group = NULL;
691 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
692 GtkWidget *size_menu_item;
694 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
695 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
696 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
697 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
698 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
699 gtk_widget_show (size_menu_item);
701 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
703 g_signal_connect (G_OBJECT (size_menu_item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
706 priv->size_items_group = g_slist_reverse (priv->size_items_group);
707 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
708 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
709 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
710 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
711 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
712 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
713 priv->font_size_toolitem = tool_item;
716 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
717 priv->font_tool_button_label = gtk_label_new (NULL);
718 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
719 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
721 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
722 fonts_menu = gtk_menu_new ();
723 priv->font_items_group = NULL;
725 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
726 GtkWidget *font_menu_item;
727 GtkWidget *child_label;
729 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
730 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
731 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
732 wp_get_font_name (font_index), "</span>", NULL);
733 gtk_label_set_markup (GTK_LABEL (child_label), markup);
736 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
737 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
738 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
739 gtk_widget_show (font_menu_item);
741 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
743 g_signal_connect (G_OBJECT (font_menu_item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
746 priv->font_items_group = g_slist_reverse (priv->font_items_group);
747 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
748 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
749 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
750 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
751 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
752 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
753 priv->font_face_toolitem = tool_item;
755 /* Set expand and homogeneous for remaining items */
756 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
757 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
758 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
759 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
760 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
761 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
762 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
763 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
764 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
772 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
775 ModestWindowPrivate *parent_priv;
776 ModestMsgEditWindowPrivate *priv;
777 GtkActionGroup *action_group;
778 GError *error = NULL;
779 GdkPixbuf *window_icon = NULL;
781 g_return_val_if_fail (msg, NULL);
783 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
785 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
786 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
788 parent_priv->ui_manager = gtk_ui_manager_new();
789 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
790 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
792 /* Add common actions */
793 gtk_action_group_add_actions (action_group,
794 modest_msg_edit_action_entries,
795 G_N_ELEMENTS (modest_msg_edit_action_entries),
797 gtk_action_group_add_toggle_actions (action_group,
798 modest_msg_edit_toggle_action_entries,
799 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
801 gtk_action_group_add_radio_actions (action_group,
802 modest_msg_edit_alignment_radio_action_entries,
803 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
805 G_CALLBACK (modest_ui_actions_on_change_justify),
807 gtk_action_group_add_radio_actions (action_group,
808 modest_msg_edit_zoom_action_entries,
809 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
811 G_CALLBACK (modest_ui_actions_on_change_zoom),
813 gtk_action_group_add_radio_actions (action_group,
814 modest_msg_edit_priority_action_entries,
815 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
817 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
819 gtk_action_group_add_radio_actions (action_group,
820 modest_msg_edit_file_format_action_entries,
821 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
822 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
823 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
825 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
826 g_object_unref (action_group);
828 /* Load the UI definition */
829 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml", &error);
831 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
832 g_error_free (error);
836 /* Add accelerators */
837 gtk_window_add_accel_group (GTK_WINDOW (obj),
838 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
841 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
842 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
845 init_window (MODEST_MSG_EDIT_WINDOW(obj));
847 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
849 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
850 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
852 g_signal_connect (G_OBJECT(obj), "delete-event",
853 G_CALLBACK(on_delete_event), obj);
855 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
857 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
859 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
861 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
863 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
865 /* Set window icon */
866 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
867 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
869 return (ModestWindow*)obj;
873 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
875 GString **string_buffer = (GString **) user_data;
877 *string_buffer = g_string_append (*string_buffer, buffer);
883 get_formatted_data (ModestMsgEditWindow *edit_window)
885 ModestMsgEditWindowPrivate *priv;
886 GString *string_buffer = g_string_new ("");
888 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
890 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
892 return g_string_free (string_buffer, FALSE);
897 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
900 const gchar *account_name;
903 ModestMsgEditWindowPrivate *priv;
905 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
907 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
909 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
910 g_return_val_if_fail (account_name, NULL);
912 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
913 gtk_text_buffer_get_bounds (buf, &b, &e);
915 /* don't free these (except from) */
916 data = g_slice_new0 (MsgData);
917 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
919 data->to = (gchar*) modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR(priv->to_field));
920 data->cc = (gchar*) modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR(priv->cc_field));
921 data->bcc = (gchar*) modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR(priv->bcc_field));
922 data->subject = (gchar*) gtk_entry_get_text (GTK_ENTRY(priv->subject_field));
923 data->plain_body = (gchar *) gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE);
924 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
925 data->html_body = get_formatted_data (edit_window);
927 data->html_body = NULL;
928 data->attachments = priv->attachments;
929 data->priority_flags = priv->priority_flags;
935 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
938 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
941 g_free (data->html_body);
942 g_free (data->plain_body);
943 g_slice_free (MsgData, data);
947 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
950 ModestMsgEditWindowPrivate *priv = NULL;
951 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
953 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
955 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
957 return MODEST_MSG_EDIT_FORMAT_HTML;
959 return MODEST_MSG_EDIT_FORMAT_TEXT;
963 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
964 ModestMsgEditFormat format)
966 ModestMsgEditWindowPrivate *priv;
968 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
969 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
972 case MODEST_MSG_EDIT_FORMAT_HTML:
973 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
975 case MODEST_MSG_EDIT_FORMAT_TEXT:
976 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
979 g_return_if_reached ();
983 ModestMsgEditFormatState *
984 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
986 ModestMsgEditFormatState *format_state = NULL;
987 ModestMsgEditWindowPrivate *priv;
988 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
990 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
991 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
993 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
995 format_state = g_new0 (ModestMsgEditFormatState, 1);
996 format_state->bold = buffer_format->bold&0x1;
997 format_state->italics = buffer_format->italic&0x1;
998 format_state->bullet = buffer_format->bullet&0x1;
999 format_state->color = buffer_format->color;
1000 format_state->font_size = buffer_format->font_size;
1001 format_state->font_family = wp_get_font_name (buffer_format->font);
1002 format_state->justification = buffer_format->justification;
1003 g_free (buffer_format);
1005 return format_state;
1010 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1011 const ModestMsgEditFormatState *format_state)
1013 ModestMsgEditWindowPrivate *priv;
1014 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1015 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1016 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1017 g_return_if_fail (format_state != NULL);
1019 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1020 gtk_widget_grab_focus (priv->msg_body);
1021 buffer_format->bold = (format_state->bold != FALSE);
1022 buffer_format->italic = (format_state->italics != FALSE);
1023 buffer_format->color = format_state->color;
1024 buffer_format->font_size = format_state->font_size;
1025 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1026 buffer_format->justification = format_state->justification;
1027 buffer_format->bullet = format_state->bullet;
1029 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1031 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1032 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1033 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1034 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1035 buffer_format->cs.font = (buffer_format->font != current_format->font);
1036 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1037 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1039 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1040 if (buffer_format->cs.bold) {
1041 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1043 if (buffer_format->cs.italic) {
1044 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1046 if (buffer_format->cs.color) {
1047 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1049 if (buffer_format->cs.font_size) {
1050 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1052 if (buffer_format->cs.justification) {
1053 switch (buffer_format->justification) {
1054 case GTK_JUSTIFY_LEFT:
1055 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1057 case GTK_JUSTIFY_CENTER:
1058 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1060 case GTK_JUSTIFY_RIGHT:
1061 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1068 if (buffer_format->cs.font) {
1069 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1071 if (buffer_format->cs.bullet) {
1072 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
1074 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1075 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1077 g_free (current_format);
1082 toggle_action_set_active_block_notify (GtkToggleAction *action,
1085 GSList *proxies = NULL;
1087 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1088 proxies != NULL; proxies = g_slist_next (proxies)) {
1089 GtkWidget *widget = (GtkWidget *) proxies->data;
1090 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1093 gtk_toggle_action_set_active (action, value);
1095 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1096 proxies != NULL; proxies = g_slist_next (proxies)) {
1097 GtkWidget *widget = (GtkWidget *) proxies->data;
1098 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1103 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1105 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1107 ModestWindowPrivate *parent_priv;
1108 ModestMsgEditWindowPrivate *priv;
1109 GtkWidget *new_size_menuitem;
1110 GtkWidget *new_font_menuitem;
1112 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1113 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1115 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1116 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1117 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1118 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1120 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1121 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1122 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1125 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1127 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1128 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1130 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1131 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1133 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1134 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1136 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1137 G_CALLBACK (modest_msg_edit_window_color_button_change),
1139 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1140 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1141 G_CALLBACK (modest_msg_edit_window_color_button_change),
1144 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1145 buffer_format->font_size))->data);
1146 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1150 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1151 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1152 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1154 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1155 G_CALLBACK (modest_msg_edit_window_size_change),
1157 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1158 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1159 G_CALLBACK (modest_msg_edit_window_size_change),
1163 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1164 buffer_format->font))->data);
1165 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1169 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1170 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1171 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1173 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1174 G_CALLBACK (modest_msg_edit_window_font_change),
1176 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1177 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1178 G_CALLBACK (modest_msg_edit_window_font_change),
1182 g_free (buffer_format);
1188 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1191 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1192 ModestMsgEditWindowPrivate *priv;
1193 GtkWidget *dialog = NULL;
1195 const GdkColor *new_color = NULL;
1197 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1198 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1200 #ifdef MODEST_HILDON_VERSION_0
1201 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1202 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1204 dialog = hildon_color_chooser_new ();
1205 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1206 #endif /*MODEST_HILDON_VERSION_0*/
1207 g_free (buffer_format);
1209 response = gtk_dialog_run (GTK_DIALOG (dialog));
1211 case GTK_RESPONSE_OK: {
1212 #ifdef MODEST_HILDON_VERSION_0
1213 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1216 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1218 #endif /*MODEST_HILDON_VERSION_0*/
1225 gtk_widget_destroy (dialog);
1227 if (new_color != NULL)
1228 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1233 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1236 ModestMsgEditWindowPrivate *priv;
1237 GtkWidget *dialog = NULL;
1239 GdkColor *old_color = NULL;
1240 const GdkColor *new_color = NULL;
1242 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1243 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1245 #ifdef MODEST_HILDON_VERSION_0
1246 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1247 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1249 dialog = hildon_color_chooser_new ();
1250 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1251 #endif /*MODEST_HILDON_VERSION_9*/
1253 response = gtk_dialog_run (GTK_DIALOG (dialog));
1255 case GTK_RESPONSE_OK: {
1256 #ifdef MODEST_HILDON_VERSION_0
1257 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1260 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1262 #endif /*MODEST_HILDON_VERSION_0*/
1268 gtk_widget_destroy (dialog);
1270 if (new_color != NULL)
1271 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1276 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1279 ModestMsgEditWindowPrivate *priv;
1280 GtkWidget *dialog = NULL;
1282 gchar *filename = NULL;
1284 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1286 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1288 response = gtk_dialog_run (GTK_DIALOG (dialog));
1290 case GTK_RESPONSE_OK:
1291 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1296 gtk_widget_destroy (dialog);
1299 GdkPixbuf *pixbuf = NULL;
1300 GtkTextIter position;
1301 GtkTextMark *insert_mark;
1303 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1306 GdkPixbufFormat *pixbuf_format;
1308 image_file_id = g_open (filename, O_RDONLY, 0);
1309 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1310 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1311 TnyMimePart *image_part;
1312 TnyStream *image_stream;
1318 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1319 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1320 mime_type = mime_types[0];
1322 mime_type = "image/unknown";
1324 image_part = tny_platform_factory_new_mime_part
1325 (modest_runtime_get_platform_factory ());
1326 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1328 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1329 g_strfreev (mime_types);
1331 content_id = g_strdup_printf ("%d", priv->last_cid);
1332 tny_mime_part_set_content_id (image_part, content_id);
1333 g_free (content_id);
1336 basename = g_path_get_basename (filename);
1337 tny_mime_part_set_filename (image_part, basename);
1340 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1341 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1342 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1343 priv->attachments = g_list_prepend (priv->attachments, image_part);
1344 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1346 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1347 gtk_widget_show_all (priv->attachments_caption);
1348 } else if (image_file_id == -1) {
1349 close (image_file_id);
1358 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1361 ModestMsgEditWindowPrivate *priv;
1362 GdkColor *new_color;
1363 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1365 #ifdef MODEST_HILDON_VERSION_0
1366 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1369 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1371 #endif /*MODEST_HILDON_VERSION_0*/
1373 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1375 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1380 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1383 ModestMsgEditWindowPrivate *priv;
1384 gint new_size_index;
1385 ModestMsgEditWindow *window;
1388 window = MODEST_MSG_EDIT_WINDOW (userdata);
1389 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1390 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1392 if (gtk_check_menu_item_get_active (menu_item)) {
1395 label = gtk_bin_get_child (GTK_BIN (menu_item));
1397 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1399 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1400 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1401 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1403 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1404 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1405 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1411 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1414 ModestMsgEditWindowPrivate *priv;
1415 gint new_font_index;
1416 ModestMsgEditWindow *window;
1419 window = MODEST_MSG_EDIT_WINDOW (userdata);
1420 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1421 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1423 if (gtk_check_menu_item_get_active (menu_item)) {
1426 label = gtk_bin_get_child (GTK_BIN (menu_item));
1428 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1430 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1431 (gpointer) new_font_index))
1432 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1434 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1435 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1436 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1442 modest_msg_edit_window_set_zoom (ModestWindow *window,
1445 ModestMsgEditWindowPrivate *priv;
1447 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1449 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1450 priv->zoom_level = zoom;
1451 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1455 modest_msg_edit_window_get_zoom (ModestWindow *window)
1457 ModestMsgEditWindowPrivate *priv;
1459 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1461 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1462 return priv->zoom_level;
1466 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1468 ModestWindowPrivate *parent_priv;
1469 GtkRadioAction *zoom_radio_action;
1470 GSList *group, *node;
1472 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1473 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1474 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1476 group = gtk_radio_action_get_group (zoom_radio_action);
1478 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1479 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1483 for (node = group; node != NULL; node = g_slist_next (node)) {
1484 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1485 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1493 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1495 ModestWindowPrivate *parent_priv;
1496 GtkRadioAction *zoom_radio_action;
1497 GSList *group, *node;
1499 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1500 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1501 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1503 group = gtk_radio_action_get_group (zoom_radio_action);
1505 for (node = group; node != NULL; node = g_slist_next (node)) {
1506 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1507 if (node->next != NULL) {
1508 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1511 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1519 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1521 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1522 ModestWindowPrivate *parent_priv;
1523 ModestWindowMgr *mgr;
1524 gboolean is_fullscreen;
1525 GtkAction *fs_toggle_action;
1528 mgr = modest_runtime_get_window_mgr ();
1529 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1531 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1533 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1534 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1535 if (is_fullscreen != active)
1536 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1544 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1546 ModestWindowPrivate *parent_priv;
1547 GtkAction *fs_toggle_action;
1550 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1552 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1553 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1554 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1558 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1561 ModestMsgEditWindowPrivate *priv = NULL;
1562 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1564 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1566 gtk_widget_show (priv->cc_caption);
1568 gtk_widget_hide (priv->cc_caption);
1572 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1575 ModestMsgEditWindowPrivate *priv = NULL;
1576 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1578 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1580 gtk_widget_show (priv->bcc_caption);
1582 gtk_widget_hide (priv->bcc_caption);
1586 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1587 ModestRecptEditor *editor)
1589 ModestMsgEditWindowPrivate *priv;
1591 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1592 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1593 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1595 if (editor == NULL) {
1596 GtkWidget *view_focus;
1597 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1599 /* This code should be kept in sync with ModestRecptEditor. The
1600 textview inside the recpt editor is the one that really gets the
1601 focus. As it's inside a scrolled window, and this one inside the
1602 hbox recpt editor inherits from, we'll need to go up in the
1603 hierarchy to know if the text view is part of the recpt editor
1604 or if it's a different text entry */
1606 if (gtk_widget_get_parent (view_focus)) {
1607 GtkWidget *first_parent;
1609 first_parent = gtk_widget_get_parent (view_focus);
1610 if (gtk_widget_get_parent (first_parent) &&
1611 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1612 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1617 editor = MODEST_RECPT_EDITOR (priv->to_field);
1621 modest_address_book_select_addresses (editor);
1626 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1628 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1630 modest_msg_edit_window_open_addressbook (window, NULL);
1634 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1635 gboolean show_toolbar)
1637 ModestWindowPrivate *parent_priv;
1639 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self));
1640 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1642 /* FIXME: we can not just use the code of
1643 modest_msg_edit_window_setup_toolbar because it has a
1644 mixture of both initialization and creation code. */
1647 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1649 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1653 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1654 TnyHeaderFlags priority_flags)
1656 ModestMsgEditWindowPrivate *priv;
1658 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1660 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1661 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1663 if (priv->priority_flags != priority_flags) {
1665 priv->priority_flags = priority_flags;
1667 switch (priority_flags) {
1668 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1669 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1670 gtk_widget_show (priv->priority_icon);
1672 case TNY_HEADER_FLAG_LOW_PRIORITY:
1673 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1674 gtk_widget_show (priv->priority_icon);
1677 gtk_widget_hide (priv->priority_icon);
1684 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1687 ModestMsgEditWindowPrivate *priv;
1688 gint current_format;
1690 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1692 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1694 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1695 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1697 if (current_format != file_format) {
1698 switch (file_format) {
1699 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1700 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1702 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1706 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1707 response = gtk_dialog_run (GTK_DIALOG (dialog));
1708 gtk_widget_destroy (dialog);
1709 if (response == GTK_RESPONSE_OK)
1710 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1714 update_dimmed (window);
1719 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1722 ModestMsgEditWindowPrivate *priv;
1723 WPTextBufferFormat oldfmt, fmt;
1724 gint old_position = 0;
1728 GdkColor *color = NULL;
1729 gboolean bold, bold_set, italic, italic_set;
1730 gboolean underline, underline_set;
1731 gboolean strikethrough, strikethrough_set;
1732 gboolean position_set;
1733 gboolean font_size_set, font_set, color_set;
1736 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1737 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1739 dialog = hildon_font_selection_dialog_new (NULL, NULL);
1741 /* First we get the currently selected font information */
1742 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
1743 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
1745 switch (oldfmt.text_position) {
1746 case TEXT_POSITION_NORMAL:
1749 case TEXT_POSITION_SUPERSCRIPT:
1757 g_object_set (G_OBJECT (dialog),
1758 "bold", oldfmt.bold != FALSE,
1759 "bold-set", !oldfmt.cs.bold,
1760 "underline", oldfmt.underline != FALSE,
1761 "underline-set", !oldfmt.cs.underline,
1762 "italic", oldfmt.italic != FALSE,
1763 "italic-set", !oldfmt.cs.italic,
1764 "strikethrough", oldfmt.strikethrough != FALSE,
1765 "strikethrough-set", !oldfmt.cs.strikethrough,
1766 "color", &oldfmt.color,
1767 "color-set", !oldfmt.cs.color,
1768 "size", wp_font_size[oldfmt.font_size],
1769 "size-set", !oldfmt.cs.font_size,
1770 "position", old_position,
1771 "position-set", !oldfmt.cs.text_position,
1772 "family", wp_get_font_name (oldfmt.font),
1773 "family-set", !oldfmt.cs.font,
1776 gtk_widget_show_all (dialog);
1777 response = gtk_dialog_run (GTK_DIALOG (dialog));
1778 if (response == GTK_RESPONSE_OK) {
1780 g_object_get( dialog,
1782 "bold-set", &bold_set,
1783 "underline", &underline,
1784 "underline-set", &underline_set,
1786 "italic-set", &italic_set,
1787 "strikethrough", &strikethrough,
1788 "strikethrough-set", &strikethrough_set,
1790 "color-set", &color_set,
1792 "size-set", &font_size_set,
1793 "family", &font_name,
1794 "family-set", &font_set,
1795 "position", &position,
1796 "position-set", &position_set,
1801 gtk_widget_destroy (dialog);
1803 if (response == GTK_RESPONSE_OK) {
1804 memset(&fmt, 0, sizeof(fmt));
1810 fmt.italic = italic;
1811 fmt.cs.italic = TRUE;
1813 if (underline_set) {
1814 fmt.underline = underline;
1815 fmt.cs.underline = TRUE;
1817 if (strikethrough_set) {
1818 fmt.strikethrough = strikethrough;
1819 fmt.cs.strikethrough = TRUE;
1824 ? TEXT_POSITION_NORMAL
1825 : ( ( position == 1 )
1826 ? TEXT_POSITION_SUPERSCRIPT
1827 : TEXT_POSITION_SUBSCRIPT );
1828 fmt.cs.text_position = TRUE;
1832 fmt.cs.color = TRUE;
1834 gdk_color_free(color);
1836 fmt.font = wp_get_font_index(font_name,
1841 if (font_size_set) {
1842 fmt.font_size = wp_get_font_size_index(
1843 font_size, DEFAULT_FONT_SIZE);
1844 fmt.cs.font_size = TRUE;
1846 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
1847 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
1853 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
1855 ModestMsgEditWindowPrivate *priv;
1857 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1858 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1860 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
1862 update_dimmed (window);
1867 update_dimmed (ModestMsgEditWindow *window)
1869 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1870 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1874 gboolean editor_focused;
1876 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1877 editor_focused = gtk_widget_is_focus (priv->msg_body);
1879 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
1880 gtk_action_set_sensitive (action, rich_text && editor_focused);
1881 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1882 gtk_action_set_sensitive (action, rich_text && editor_focused);
1883 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
1884 gtk_action_set_sensitive (action, rich_text && editor_focused);
1885 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1886 gtk_action_set_sensitive (action, rich_text && editor_focused);
1887 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1888 gtk_action_set_sensitive (action, rich_text && editor_focused);
1889 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1890 gtk_action_set_sensitive (action, rich_text && editor_focused);
1891 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
1892 gtk_action_set_sensitive (action, rich_text && editor_focused);
1893 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1894 gtk_action_set_sensitive (action, rich_text && editor_focused);
1895 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1896 gtk_action_set_sensitive (action, rich_text && editor_focused);
1897 widget = priv->font_color_button;
1898 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
1899 widget = priv->font_size_toolitem;
1900 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
1901 widget = priv->font_face_toolitem;
1902 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
1906 setup_insensitive_handlers (ModestMsgEditWindow *window)
1908 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1909 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1912 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1913 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
1914 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
1915 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
1917 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
1918 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1919 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1920 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1921 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
1922 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1923 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1924 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1925 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1926 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1927 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1928 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1929 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
1930 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1931 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1932 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1933 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1934 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1935 widget = priv->font_color_button;
1936 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1937 widget = priv->font_size_toolitem;
1938 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1939 widget = priv->font_face_toolitem;
1940 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1945 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
1947 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1950 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
1951 gtk_action_set_sensitive (action, can_undo);
1955 msg_body_focus (GtkWidget *focus,
1956 GdkEventFocus *event,
1959 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
1964 to_field_changed (GtkTextBuffer *buffer,
1965 ModestMsgEditWindow *editor)
1967 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
1970 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1971 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
1972 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
1973 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
1977 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
1979 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
1983 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
1985 gboolean rich_text, editor_focused;
1987 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
1988 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1989 editor_focused = gtk_widget_is_focus (priv->msg_body);
1992 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
1993 else if (!editor_focused)
1994 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
1998 reset_modified (ModestMsgEditWindow *editor)
2000 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2001 GtkTextBuffer *buffer;
2003 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2004 gtk_text_buffer_set_modified (buffer, FALSE);
2005 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2006 gtk_text_buffer_set_modified (buffer, FALSE);
2007 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2008 gtk_text_buffer_set_modified (buffer, FALSE);
2009 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2013 is_modified (ModestMsgEditWindow *editor)
2015 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2016 GtkTextBuffer *buffer;
2018 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2019 if (gtk_text_buffer_get_modified (buffer))
2021 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2022 if (gtk_text_buffer_get_modified (buffer))
2024 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2025 if (gtk_text_buffer_get_modified (buffer))
2027 if (gtk_text_buffer_get_modified (priv->text_buffer))
2034 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2036 ModestMsgEditWindowPrivate *priv = NULL;
2038 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2039 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2041 /* check if there's no recipient added */
2042 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2043 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2044 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2045 /* no recipient contents, then select contacts */
2046 modest_msg_edit_window_open_addressbook (window, NULL);
2050 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2052 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2054 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2057 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));