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 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
197 GObjectClass *gobject_class;
198 ModestWindowClass *modest_window_class;
199 gobject_class = (GObjectClass*) klass;
200 modest_window_class = (ModestWindowClass*) klass;
202 parent_class = g_type_class_peek_parent (klass);
203 gobject_class->finalize = modest_msg_edit_window_finalize;
205 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
206 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
207 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
208 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
209 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
211 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
215 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
217 ModestMsgEditWindowPrivate *priv;
218 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
220 priv->msg_body = NULL;
221 priv->from_field = NULL;
222 priv->to_field = NULL;
223 priv->cc_field = NULL;
224 priv->bcc_field = NULL;
225 priv->subject_field = NULL;
226 priv->attachments = NULL;
228 priv->zoom_level = 1.0;
230 priv->cc_caption = NULL;
231 priv->bcc_caption = NULL;
233 priv->priority_flags = 0;
235 priv->draft_msg = NULL;
241 save_settings (ModestMsgEditWindow *self)
243 modest_widget_memory_save (modest_runtime_get_conf(),
244 G_OBJECT(self), "modest-edit-msg-window");
249 restore_settings (ModestMsgEditWindow *self)
251 modest_widget_memory_restore (modest_runtime_get_conf(),
252 G_OBJECT(self), "modest-edit-msg-window");
256 /* FIXME: this is a dup from the one in gtk/ */
257 static ModestPairList*
258 get_transports (void)
260 ModestAccountMgr *account_mgr;
261 GSList *transports = NULL;
262 GSList *cursor, *accounts;
264 account_mgr = modest_runtime_get_account_mgr();
265 cursor = accounts = modest_account_mgr_account_names (account_mgr);
267 gchar *account_name = (gchar*)cursor->data;
268 gchar *from_string = modest_account_mgr_get_from_string (account_mgr,
271 /* something went wrong: ignore this one */
272 g_free (account_name);
276 pair = modest_pair_new ((gpointer) account_name,
277 (gpointer) from_string , TRUE);
278 transports = g_slist_prepend (transports, pair);
279 } /* don't free account name; it's freed when the transports list is freed */
280 cursor = cursor->next;
282 g_slist_free (accounts);
288 text_buffer_mark_set (GtkTextBuffer *buffer, GtkTextIter *iter, GtkTextMark *mark, gpointer userdata)
290 ModestMsgEditWindow *window;
291 ModestMsgEditWindowPrivate *priv;
292 GdkRectangle location;
293 gint v_scroll_min_value = 0;
294 gint v_scroll_max_value = 0;
295 gint v_scroll_visible;
297 GtkTextMark *insert_mark;
298 GtkTextIter insert_iter;
300 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (userdata));
301 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
302 window = MODEST_MSG_EDIT_WINDOW (userdata);
303 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
305 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
306 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &insert_iter, insert_mark);
307 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &insert_iter, &location);
309 if (priv->header_box)
310 v_scroll_min_value += priv->header_box->allocation.height + DEFAULT_MAIN_VBOX_SPACING;
311 v_scroll_min_value += location.y;
312 v_scroll_max_value = v_scroll_min_value + location.height;
314 v_scroll_visible = GTK_WIDGET (window)->allocation.height;
316 vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll));
318 if (((gdouble) v_scroll_min_value) < vadj->value)
319 gtk_adjustment_set_value (vadj, v_scroll_min_value);
320 else if (((gdouble) v_scroll_max_value) > (vadj->value + vadj->page_size))
321 gtk_adjustment_set_value (vadj, ((gdouble)v_scroll_max_value) - vadj->page_size);
325 init_window (ModestMsgEditWindow *obj)
327 GtkWidget *from_caption, *to_caption, *subject_caption;
328 GtkWidget *main_vbox;
329 ModestMsgEditWindowPrivate *priv;
330 ModestPairList *protos;
331 GtkSizeGroup *size_group;
333 GtkWidget *scroll_area;
334 GtkWidget *subject_box;
335 GtkWidget *attachment_icon;
337 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
339 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
341 protos = get_transports ();
342 priv->from_field = modest_combo_box_new (protos, g_str_equal);
343 modest_pair_list_free (protos);
345 priv->to_field = modest_recpt_editor_new ();
346 priv->cc_field = modest_recpt_editor_new ();
347 priv->bcc_field = modest_recpt_editor_new ();
348 subject_box = gtk_hbox_new (FALSE, 0);
349 priv->priority_icon = gtk_image_new ();
350 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
351 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
352 g_object_set (G_OBJECT (priv->subject_field), "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
353 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
354 priv->add_attachment_button = gtk_button_new ();
355 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
356 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
357 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
358 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
359 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
360 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
361 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
362 priv->attachments_view = modest_attachments_view_new (NULL);
364 priv->header_box = gtk_vbox_new (FALSE, 0);
366 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
367 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
368 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
369 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
370 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
371 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
372 g_object_unref (size_group);
374 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
375 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
376 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
377 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
378 gtk_size_group_add_widget (size_group, priv->subject_field);
379 gtk_size_group_add_widget (size_group, priv->attachments_view);
380 g_object_unref (size_group);
382 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
383 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
384 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
385 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
386 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
387 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
388 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
391 priv->msg_body = wp_text_view_new ();
392 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
393 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
394 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
395 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
396 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
397 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
399 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
400 G_CALLBACK (text_buffer_refresh_attributes), obj);
401 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
402 G_CALLBACK (text_buffer_mark_set), obj);
403 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
404 G_CALLBACK (text_buffer_can_undo), obj);
405 g_signal_connect (G_OBJECT (obj), "window-state-event",
406 G_CALLBACK (modest_msg_edit_window_window_state_event),
408 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
409 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
410 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
411 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
412 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
413 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
415 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
416 G_CALLBACK (msg_body_focus), obj);
417 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
418 G_CALLBACK (msg_body_focus), obj);
419 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
420 "changed", G_CALLBACK (to_field_changed), obj);
421 to_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
423 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
424 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
425 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
427 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
429 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
430 frame = gtk_frame_new (NULL);
431 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
433 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
434 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
435 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
437 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL))
438 gtk_widget_hide (priv->cc_field);
439 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL))
440 gtk_widget_hide (priv->bcc_field);
442 gtk_container_add (GTK_CONTAINER(obj), priv->scroll);
443 scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
444 gtk_container_add (GTK_CONTAINER (frame), scroll_area);
445 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
446 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
452 modest_msg_edit_window_finalize (GObject *obj)
454 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 save_settings (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 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1641 /* FIXME: we can not just use the code of
1642 modest_msg_edit_window_setup_toolbar because it has a
1643 mixture of both initialization and creation code. */
1646 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1648 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1652 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1653 TnyHeaderFlags priority_flags)
1655 ModestMsgEditWindowPrivate *priv;
1657 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1659 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1660 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1662 if (priv->priority_flags != priority_flags) {
1664 priv->priority_flags = priority_flags;
1666 switch (priority_flags) {
1667 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1668 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1669 gtk_widget_show (priv->priority_icon);
1671 case TNY_HEADER_FLAG_LOW_PRIORITY:
1672 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1673 gtk_widget_show (priv->priority_icon);
1676 gtk_widget_hide (priv->priority_icon);
1683 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1686 ModestMsgEditWindowPrivate *priv;
1687 gint current_format;
1689 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1691 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1693 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1694 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1696 if (current_format != file_format) {
1697 switch (file_format) {
1698 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1699 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1701 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1705 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1706 response = gtk_dialog_run (GTK_DIALOG (dialog));
1707 gtk_widget_destroy (dialog);
1708 if (response == GTK_RESPONSE_OK)
1709 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1713 update_dimmed (window);
1718 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1721 ModestMsgEditWindowPrivate *priv;
1722 WPTextBufferFormat oldfmt, fmt;
1723 gint old_position = 0;
1727 GdkColor *color = NULL;
1728 gboolean bold, bold_set, italic, italic_set;
1729 gboolean underline, underline_set;
1730 gboolean strikethrough, strikethrough_set;
1731 gboolean position_set;
1732 gboolean font_size_set, font_set, color_set;
1735 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1736 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1738 dialog = hildon_font_selection_dialog_new (NULL, NULL);
1740 /* First we get the currently selected font information */
1741 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
1742 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
1744 switch (oldfmt.text_position) {
1745 case TEXT_POSITION_NORMAL:
1748 case TEXT_POSITION_SUPERSCRIPT:
1756 g_object_set (G_OBJECT (dialog),
1757 "bold", oldfmt.bold != FALSE,
1758 "bold-set", !oldfmt.cs.bold,
1759 "underline", oldfmt.underline != FALSE,
1760 "underline-set", !oldfmt.cs.underline,
1761 "italic", oldfmt.italic != FALSE,
1762 "italic-set", !oldfmt.cs.italic,
1763 "strikethrough", oldfmt.strikethrough != FALSE,
1764 "strikethrough-set", !oldfmt.cs.strikethrough,
1765 "color", &oldfmt.color,
1766 "color-set", !oldfmt.cs.color,
1767 "size", wp_font_size[oldfmt.font_size],
1768 "size-set", !oldfmt.cs.font_size,
1769 "position", old_position,
1770 "position-set", !oldfmt.cs.text_position,
1771 "family", wp_get_font_name (oldfmt.font),
1772 "family-set", !oldfmt.cs.font,
1775 gtk_widget_show_all (dialog);
1776 response = gtk_dialog_run (GTK_DIALOG (dialog));
1777 if (response == GTK_RESPONSE_OK) {
1779 g_object_get( dialog,
1781 "bold-set", &bold_set,
1782 "underline", &underline,
1783 "underline-set", &underline_set,
1785 "italic-set", &italic_set,
1786 "strikethrough", &strikethrough,
1787 "strikethrough-set", &strikethrough_set,
1789 "color-set", &color_set,
1791 "size-set", &font_size_set,
1792 "family", &font_name,
1793 "family-set", &font_set,
1794 "position", &position,
1795 "position-set", &position_set,
1800 gtk_widget_destroy (dialog);
1802 if (response == GTK_RESPONSE_OK) {
1803 memset(&fmt, 0, sizeof(fmt));
1809 fmt.italic = italic;
1810 fmt.cs.italic = TRUE;
1812 if (underline_set) {
1813 fmt.underline = underline;
1814 fmt.cs.underline = TRUE;
1816 if (strikethrough_set) {
1817 fmt.strikethrough = strikethrough;
1818 fmt.cs.strikethrough = TRUE;
1823 ? TEXT_POSITION_NORMAL
1824 : ( ( position == 1 )
1825 ? TEXT_POSITION_SUPERSCRIPT
1826 : TEXT_POSITION_SUBSCRIPT );
1827 fmt.cs.text_position = TRUE;
1831 fmt.cs.color = TRUE;
1833 gdk_color_free(color);
1835 fmt.font = wp_get_font_index(font_name,
1840 if (font_size_set) {
1841 fmt.font_size = wp_get_font_size_index(
1842 font_size, DEFAULT_FONT_SIZE);
1843 fmt.cs.font_size = TRUE;
1845 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
1846 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
1852 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
1854 ModestMsgEditWindowPrivate *priv;
1856 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1857 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1859 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
1861 update_dimmed (window);
1866 update_dimmed (ModestMsgEditWindow *window)
1868 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1869 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1873 gboolean editor_focused;
1875 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1876 editor_focused = gtk_widget_is_focus (priv->msg_body);
1878 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
1879 gtk_action_set_sensitive (action, rich_text && editor_focused);
1880 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1881 gtk_action_set_sensitive (action, rich_text && editor_focused);
1882 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
1883 gtk_action_set_sensitive (action, rich_text && editor_focused);
1884 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1885 gtk_action_set_sensitive (action, rich_text && editor_focused);
1886 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1887 gtk_action_set_sensitive (action, rich_text && editor_focused);
1888 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1889 gtk_action_set_sensitive (action, rich_text && editor_focused);
1890 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
1891 gtk_action_set_sensitive (action, rich_text && editor_focused);
1892 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1893 gtk_action_set_sensitive (action, rich_text && editor_focused);
1894 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1895 gtk_action_set_sensitive (action, rich_text && editor_focused);
1896 widget = priv->font_color_button;
1897 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
1898 widget = priv->font_size_toolitem;
1899 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
1900 widget = priv->font_face_toolitem;
1901 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
1905 setup_insensitive_handlers (ModestMsgEditWindow *window)
1907 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1908 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1911 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1912 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
1913 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
1914 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
1916 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
1917 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1918 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1919 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1920 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
1921 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1922 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1923 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1924 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1925 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1926 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1927 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1928 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
1929 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1930 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1931 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1932 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1933 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1934 widget = priv->font_color_button;
1935 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1936 widget = priv->font_size_toolitem;
1937 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1938 widget = priv->font_face_toolitem;
1939 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1944 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
1946 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1949 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
1950 gtk_action_set_sensitive (action, can_undo);
1954 msg_body_focus (GtkWidget *focus,
1955 GdkEventFocus *event,
1958 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
1963 to_field_changed (GtkTextBuffer *buffer,
1964 ModestMsgEditWindow *editor)
1966 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
1969 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1970 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
1971 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
1972 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
1976 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
1978 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
1982 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
1984 gboolean rich_text, editor_focused;
1986 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
1987 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1988 editor_focused = gtk_widget_is_focus (priv->msg_body);
1991 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
1992 else if (!editor_focused)
1993 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
1997 reset_modified (ModestMsgEditWindow *editor)
1999 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2000 GtkTextBuffer *buffer;
2002 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2003 gtk_text_buffer_set_modified (buffer, FALSE);
2004 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2005 gtk_text_buffer_set_modified (buffer, FALSE);
2006 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2007 gtk_text_buffer_set_modified (buffer, FALSE);
2008 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2012 is_modified (ModestMsgEditWindow *editor)
2014 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2015 GtkTextBuffer *buffer;
2017 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2018 if (gtk_text_buffer_get_modified (buffer))
2020 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2021 if (gtk_text_buffer_get_modified (buffer))
2023 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2024 if (gtk_text_buffer_get_modified (buffer))
2026 if (gtk_text_buffer_get_modified (priv->text_buffer))