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_CONF_EDIT_WINDOW_KEY);
249 restore_settings (ModestMsgEditWindow *self)
251 modest_widget_memory_restore (modest_runtime_get_conf(),
252 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
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,
266 TRUE /* only enabled accounts. */);
268 gchar *account_name = (gchar*)cursor->data;
269 gchar *from_string = modest_account_mgr_get_from_string (account_mgr,
272 /* something went wrong: ignore this one */
273 g_free (account_name);
277 pair = modest_pair_new ((gpointer) account_name,
278 (gpointer) from_string , TRUE);
279 transports = g_slist_prepend (transports, pair);
280 } /* don't free account name; it's freed when the transports list is freed */
281 cursor = cursor->next;
283 g_slist_free (accounts);
289 text_buffer_mark_set (GtkTextBuffer *buffer, GtkTextIter *iter, GtkTextMark *mark, gpointer userdata)
291 ModestMsgEditWindow *window;
292 ModestMsgEditWindowPrivate *priv;
293 GdkRectangle location;
294 gint v_scroll_min_value = 0;
295 gint v_scroll_max_value = 0;
296 gint v_scroll_visible;
298 GtkTextMark *insert_mark;
299 GtkTextIter insert_iter;
301 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (userdata));
302 g_return_if_fail (GTK_IS_TEXT_MARK (mark));
303 window = MODEST_MSG_EDIT_WINDOW (userdata);
304 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
306 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
307 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &insert_iter, insert_mark);
308 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &insert_iter, &location);
310 if (priv->header_box)
311 v_scroll_min_value += priv->header_box->allocation.height + DEFAULT_MAIN_VBOX_SPACING;
312 v_scroll_min_value += location.y;
313 v_scroll_max_value = v_scroll_min_value + location.height;
315 v_scroll_visible = GTK_WIDGET (window)->allocation.height;
317 vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll));
319 if (((gdouble) v_scroll_min_value) < vadj->value)
320 gtk_adjustment_set_value (vadj, v_scroll_min_value);
321 else if (((gdouble) v_scroll_max_value) > (vadj->value + vadj->page_size))
322 gtk_adjustment_set_value (vadj, ((gdouble)v_scroll_max_value) - vadj->page_size);
326 init_window (ModestMsgEditWindow *obj)
328 GtkWidget *from_caption, *to_caption, *subject_caption;
329 GtkWidget *main_vbox;
330 ModestMsgEditWindowPrivate *priv;
331 ModestPairList *protos;
332 GtkSizeGroup *size_group;
334 GtkWidget *scroll_area;
335 GtkWidget *subject_box;
336 GtkWidget *attachment_icon;
338 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
340 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
342 protos = get_transports ();
343 priv->from_field = modest_combo_box_new (protos, g_str_equal);
344 modest_pair_list_free (protos);
346 priv->to_field = modest_recpt_editor_new ();
347 priv->cc_field = modest_recpt_editor_new ();
348 priv->bcc_field = modest_recpt_editor_new ();
349 subject_box = gtk_hbox_new (FALSE, 0);
350 priv->priority_icon = gtk_image_new ();
351 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
352 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
353 g_object_set (G_OBJECT (priv->subject_field), "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
354 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
355 priv->add_attachment_button = gtk_button_new ();
356 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
357 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
358 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
359 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
360 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
361 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
362 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
363 priv->attachments_view = modest_attachments_view_new (NULL);
365 priv->header_box = gtk_vbox_new (FALSE, 0);
367 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
368 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
369 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
370 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
371 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
372 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
373 g_object_unref (size_group);
375 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
376 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
377 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
378 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
379 gtk_size_group_add_widget (size_group, priv->subject_field);
380 gtk_size_group_add_widget (size_group, priv->attachments_view);
381 g_object_unref (size_group);
383 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
384 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
385 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
386 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
387 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
388 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
389 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
392 priv->msg_body = wp_text_view_new ();
393 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
394 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
395 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
396 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
397 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
398 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
400 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
401 G_CALLBACK (text_buffer_refresh_attributes), obj);
402 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
403 G_CALLBACK (text_buffer_mark_set), obj);
404 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
405 G_CALLBACK (text_buffer_can_undo), obj);
406 g_signal_connect (G_OBJECT (obj), "window-state-event",
407 G_CALLBACK (modest_msg_edit_window_window_state_event),
409 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
410 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
411 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
412 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
413 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
414 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
416 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
417 G_CALLBACK (msg_body_focus), obj);
418 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
419 G_CALLBACK (msg_body_focus), obj);
420 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
421 "changed", G_CALLBACK (to_field_changed), obj);
422 to_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
424 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
425 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
426 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
428 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
430 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
431 frame = gtk_frame_new (NULL);
432 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
434 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
435 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
436 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
438 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL))
439 gtk_widget_hide (priv->cc_field);
440 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL))
441 gtk_widget_hide (priv->bcc_field);
443 gtk_container_add (GTK_CONTAINER(obj), priv->scroll);
444 scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
445 gtk_container_add (GTK_CONTAINER (frame), scroll_area);
446 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
447 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
453 modest_msg_edit_window_finalize (GObject *obj)
455 G_OBJECT_CLASS(parent_class)->finalize (obj);
461 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
463 GtkWidget *close_dialog;
464 ModestMsgEditWindowPrivate *priv;
467 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
468 save_settings (self);
469 if (is_modified (self)) {
470 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
471 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
472 gtk_widget_destroy (close_dialog);
474 if (response != GTK_RESPONSE_CANCEL) {
475 modest_ui_actions_on_save_to_drafts (NULL, self);
478 /* /\* remove old message from drafts *\/ */
479 /* if (priv->draft_msg) { */
480 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
481 /* TnyAccount *account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(), */
483 /* TNY_ACCOUNT_TYPE_STORE); */
484 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
485 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
486 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
487 /* tny_folder_remove_msg (folder, header, NULL); */
488 /* g_object_unref (folder); */
489 /* g_object_unref (header); */
490 /* g_object_unref (priv->draft_msg); */
491 /* priv->draft_msg = NULL; */
493 gtk_widget_destroy (GTK_WIDGET (self));
499 menubar_to_menu (GtkUIManager *ui_manager)
501 GtkWidget *main_menu;
505 /* Create new main menu */
506 main_menu = gtk_menu_new();
508 /* Get the menubar from the UI manager */
509 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
511 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
515 menu = GTK_WIDGET (iter->data);
516 gtk_widget_reparent(menu, main_menu);
518 iter = g_list_next (iter);
525 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
528 const gchar *to, *cc, *bcc, *subject;
530 ModestMsgEditWindowPrivate *priv;
533 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
534 g_return_if_fail (TNY_IS_MSG (msg));
536 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
538 header = tny_msg_get_header (msg);
539 to = tny_header_get_to (header);
540 cc = tny_header_get_cc (header);
541 bcc = tny_header_get_bcc (header);
542 subject = tny_header_get_subject (header);
545 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
547 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
549 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
551 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
553 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
554 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
555 body = modest_tny_msg_get_body (msg, FALSE);
557 if ((body == NULL)||(body[0] == '\0')) {
559 body = modest_text_utils_convert_to_html ("");
561 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
562 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
565 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
568 /* Get the default format required from configuration */
569 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
570 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
573 /* Set the default focus depending on having already a To: field or not */
574 if ((!to)||(*to == '\0')) {
575 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
577 gtk_widget_grab_focus (priv->msg_body);
580 /* TODO: lower priority, select in the From: combo to the
581 value that comes from msg <- not sure, should it be
584 /* Add attachments to the view */
585 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
586 if (priv->attachments == NULL)
587 gtk_widget_hide_all (priv->attachments_caption);
589 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
590 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
592 reset_modified (self);
594 update_dimmed (self);
595 text_buffer_can_undo (priv->text_buffer, FALSE, self);
597 priv->draft_msg = msg;
601 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
604 GList *item_children, *node;
605 GtkWidget *bin_child;
607 bin_child = gtk_bin_get_child (GTK_BIN(item));
609 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
611 for (node = item_children; node != NULL; node = g_list_next (node)) {
612 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
613 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
616 g_list_free (item_children);
620 menu_tool_button_dont_expand (GtkMenuToolButton *item)
623 GList *item_children, *node;
625 box = gtk_bin_get_child (GTK_BIN (item));
626 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
627 item_children = gtk_container_get_children (GTK_CONTAINER (box));
629 for (node = item_children; node != NULL; node = g_list_next (node)) {
630 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
631 if (GTK_IS_TOGGLE_BUTTON (node->data))
632 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
633 else if (GTK_IS_BUTTON (node->data))
634 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
636 g_list_free (item_children);
641 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
643 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
644 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
645 GtkWidget *placeholder;
646 GtkWidget *tool_item;
651 GtkWidget *sizes_menu;
652 GtkWidget *fonts_menu;
653 GSList *radio_group = NULL;
657 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
658 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
660 /* should we hide the toolbar? */
661 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
662 gtk_widget_hide (parent_priv->toolbar);
664 /* Font color placeholder */
665 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
666 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
669 tool_item = GTK_WIDGET (gtk_tool_item_new ());
670 priv->font_color_button = hildon_color_button_new ();
671 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
672 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
673 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
674 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
675 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
677 /* Font size and face placeholder */
678 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
679 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
681 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
682 priv->size_tool_button_label = gtk_label_new (NULL);
683 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
684 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
685 size_text,"</span>", NULL);
686 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
688 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
689 sizes_menu = gtk_menu_new ();
690 priv->size_items_group = NULL;
692 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
693 GtkWidget *size_menu_item;
695 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
696 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
697 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
698 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
699 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
700 gtk_widget_show (size_menu_item);
702 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
704 g_signal_connect (G_OBJECT (size_menu_item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
707 priv->size_items_group = g_slist_reverse (priv->size_items_group);
708 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
709 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
710 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
711 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
712 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
713 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
714 priv->font_size_toolitem = tool_item;
717 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
718 priv->font_tool_button_label = gtk_label_new (NULL);
719 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
720 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
722 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
723 fonts_menu = gtk_menu_new ();
724 priv->font_items_group = NULL;
726 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
727 GtkWidget *font_menu_item;
728 GtkWidget *child_label;
730 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
731 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
732 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
733 wp_get_font_name (font_index), "</span>", NULL);
734 gtk_label_set_markup (GTK_LABEL (child_label), markup);
737 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
738 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
739 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
740 gtk_widget_show (font_menu_item);
742 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
744 g_signal_connect (G_OBJECT (font_menu_item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
747 priv->font_items_group = g_slist_reverse (priv->font_items_group);
748 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
749 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
750 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
751 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
752 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
753 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
754 priv->font_face_toolitem = tool_item;
756 /* Set expand and homogeneous for remaining items */
757 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
758 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
759 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
760 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
761 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
762 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
763 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
764 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
765 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
773 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
776 ModestWindowPrivate *parent_priv;
777 ModestMsgEditWindowPrivate *priv;
778 GtkActionGroup *action_group;
779 GError *error = NULL;
780 GdkPixbuf *window_icon = NULL;
782 g_return_val_if_fail (msg, NULL);
784 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
786 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
787 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
789 parent_priv->ui_manager = gtk_ui_manager_new();
790 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
791 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
793 /* Add common actions */
794 gtk_action_group_add_actions (action_group,
795 modest_msg_edit_action_entries,
796 G_N_ELEMENTS (modest_msg_edit_action_entries),
798 gtk_action_group_add_toggle_actions (action_group,
799 modest_msg_edit_toggle_action_entries,
800 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
802 gtk_action_group_add_radio_actions (action_group,
803 modest_msg_edit_alignment_radio_action_entries,
804 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
806 G_CALLBACK (modest_ui_actions_on_change_justify),
808 gtk_action_group_add_radio_actions (action_group,
809 modest_msg_edit_zoom_action_entries,
810 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
812 G_CALLBACK (modest_ui_actions_on_change_zoom),
814 gtk_action_group_add_radio_actions (action_group,
815 modest_msg_edit_priority_action_entries,
816 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
818 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
820 gtk_action_group_add_radio_actions (action_group,
821 modest_msg_edit_file_format_action_entries,
822 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
823 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
824 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
826 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
827 g_object_unref (action_group);
829 /* Load the UI definition */
830 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml", &error);
832 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
833 g_error_free (error);
837 /* Add accelerators */
838 gtk_window_add_accel_group (GTK_WINDOW (obj),
839 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
842 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
843 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
846 init_window (MODEST_MSG_EDIT_WINDOW(obj));
848 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
850 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
851 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
853 g_signal_connect (G_OBJECT(obj), "delete-event",
854 G_CALLBACK(on_delete_event), obj);
856 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
858 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
860 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
862 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
864 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
866 /* Set window icon */
867 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
868 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
870 return (ModestWindow*)obj;
874 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
876 GString **string_buffer = (GString **) user_data;
878 *string_buffer = g_string_append (*string_buffer, buffer);
884 get_formatted_data (ModestMsgEditWindow *edit_window)
886 ModestMsgEditWindowPrivate *priv;
887 GString *string_buffer = g_string_new ("");
889 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
891 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
893 return g_string_free (string_buffer, FALSE);
898 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
901 const gchar *account_name;
904 ModestMsgEditWindowPrivate *priv;
906 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
908 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
910 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
911 g_return_val_if_fail (account_name, NULL);
913 buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
914 gtk_text_buffer_get_bounds (buf, &b, &e);
916 /* don't free these (except from) */
917 data = g_slice_new0 (MsgData);
918 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
920 data->to = (gchar*) modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR(priv->to_field));
921 data->cc = (gchar*) modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR(priv->cc_field));
922 data->bcc = (gchar*) modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR(priv->bcc_field));
923 data->subject = (gchar*) gtk_entry_get_text (GTK_ENTRY(priv->subject_field));
924 data->plain_body = (gchar *) gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE);
925 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
926 data->html_body = get_formatted_data (edit_window);
928 data->html_body = NULL;
929 data->attachments = priv->attachments;
930 data->priority_flags = priv->priority_flags;
936 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
939 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
942 g_free (data->html_body);
943 g_free (data->plain_body);
944 g_slice_free (MsgData, data);
948 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
951 ModestMsgEditWindowPrivate *priv = NULL;
952 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
954 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
956 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
958 return MODEST_MSG_EDIT_FORMAT_HTML;
960 return MODEST_MSG_EDIT_FORMAT_TEXT;
964 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
965 ModestMsgEditFormat format)
967 ModestMsgEditWindowPrivate *priv;
969 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
970 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
973 case MODEST_MSG_EDIT_FORMAT_HTML:
974 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
976 case MODEST_MSG_EDIT_FORMAT_TEXT:
977 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
980 g_return_if_reached ();
984 ModestMsgEditFormatState *
985 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
987 ModestMsgEditFormatState *format_state = NULL;
988 ModestMsgEditWindowPrivate *priv;
989 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
991 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
992 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
994 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
996 format_state = g_new0 (ModestMsgEditFormatState, 1);
997 format_state->bold = buffer_format->bold&0x1;
998 format_state->italics = buffer_format->italic&0x1;
999 format_state->bullet = buffer_format->bullet&0x1;
1000 format_state->color = buffer_format->color;
1001 format_state->font_size = buffer_format->font_size;
1002 format_state->font_family = wp_get_font_name (buffer_format->font);
1003 format_state->justification = buffer_format->justification;
1004 g_free (buffer_format);
1006 return format_state;
1011 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1012 const ModestMsgEditFormatState *format_state)
1014 ModestMsgEditWindowPrivate *priv;
1015 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1016 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1017 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1018 g_return_if_fail (format_state != NULL);
1020 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1021 gtk_widget_grab_focus (priv->msg_body);
1022 buffer_format->bold = (format_state->bold != FALSE);
1023 buffer_format->italic = (format_state->italics != FALSE);
1024 buffer_format->color = format_state->color;
1025 buffer_format->font_size = format_state->font_size;
1026 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1027 buffer_format->justification = format_state->justification;
1028 buffer_format->bullet = format_state->bullet;
1030 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1032 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1033 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1034 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1035 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1036 buffer_format->cs.font = (buffer_format->font != current_format->font);
1037 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1038 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1040 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1041 if (buffer_format->cs.bold) {
1042 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1044 if (buffer_format->cs.italic) {
1045 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1047 if (buffer_format->cs.color) {
1048 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1050 if (buffer_format->cs.font_size) {
1051 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1053 if (buffer_format->cs.justification) {
1054 switch (buffer_format->justification) {
1055 case GTK_JUSTIFY_LEFT:
1056 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1058 case GTK_JUSTIFY_CENTER:
1059 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1061 case GTK_JUSTIFY_RIGHT:
1062 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1069 if (buffer_format->cs.font) {
1070 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1072 if (buffer_format->cs.bullet) {
1073 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
1075 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1076 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1078 g_free (current_format);
1083 toggle_action_set_active_block_notify (GtkToggleAction *action,
1086 GSList *proxies = NULL;
1088 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1089 proxies != NULL; proxies = g_slist_next (proxies)) {
1090 GtkWidget *widget = (GtkWidget *) proxies->data;
1091 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1094 gtk_toggle_action_set_active (action, value);
1096 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1097 proxies != NULL; proxies = g_slist_next (proxies)) {
1098 GtkWidget *widget = (GtkWidget *) proxies->data;
1099 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1104 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1106 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1108 ModestWindowPrivate *parent_priv;
1109 ModestMsgEditWindowPrivate *priv;
1110 GtkWidget *new_size_menuitem;
1111 GtkWidget *new_font_menuitem;
1113 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1114 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1116 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1117 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1118 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1119 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1121 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1122 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1123 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1126 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1128 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1129 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1131 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1132 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1134 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1135 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1137 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1138 G_CALLBACK (modest_msg_edit_window_color_button_change),
1140 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1141 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1142 G_CALLBACK (modest_msg_edit_window_color_button_change),
1145 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1146 buffer_format->font_size))->data);
1147 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1151 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1152 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1153 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1155 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1156 G_CALLBACK (modest_msg_edit_window_size_change),
1158 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1159 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1160 G_CALLBACK (modest_msg_edit_window_size_change),
1164 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1165 buffer_format->font))->data);
1166 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1170 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1171 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1172 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1174 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1175 G_CALLBACK (modest_msg_edit_window_font_change),
1177 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1178 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1179 G_CALLBACK (modest_msg_edit_window_font_change),
1183 g_free (buffer_format);
1189 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1192 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1193 ModestMsgEditWindowPrivate *priv;
1194 GtkWidget *dialog = NULL;
1196 const GdkColor *new_color = NULL;
1198 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1199 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1201 #ifdef MODEST_HILDON_VERSION_0
1202 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1203 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1205 dialog = hildon_color_chooser_new ();
1206 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1207 #endif /*MODEST_HILDON_VERSION_0*/
1208 g_free (buffer_format);
1210 response = gtk_dialog_run (GTK_DIALOG (dialog));
1212 case GTK_RESPONSE_OK: {
1213 #ifdef MODEST_HILDON_VERSION_0
1214 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1217 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1219 #endif /*MODEST_HILDON_VERSION_0*/
1226 gtk_widget_destroy (dialog);
1228 if (new_color != NULL)
1229 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1234 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1237 ModestMsgEditWindowPrivate *priv;
1238 GtkWidget *dialog = NULL;
1240 GdkColor *old_color = NULL;
1241 const GdkColor *new_color = NULL;
1243 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1244 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1246 #ifdef MODEST_HILDON_VERSION_0
1247 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1248 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1250 dialog = hildon_color_chooser_new ();
1251 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1252 #endif /*MODEST_HILDON_VERSION_9*/
1254 response = gtk_dialog_run (GTK_DIALOG (dialog));
1256 case GTK_RESPONSE_OK: {
1257 #ifdef MODEST_HILDON_VERSION_0
1258 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1261 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1263 #endif /*MODEST_HILDON_VERSION_0*/
1269 gtk_widget_destroy (dialog);
1271 if (new_color != NULL)
1272 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1277 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1280 ModestMsgEditWindowPrivate *priv;
1281 GtkWidget *dialog = NULL;
1283 gchar *filename = NULL;
1285 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1287 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1289 response = gtk_dialog_run (GTK_DIALOG (dialog));
1291 case GTK_RESPONSE_OK:
1292 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1297 gtk_widget_destroy (dialog);
1300 GdkPixbuf *pixbuf = NULL;
1301 GtkTextIter position;
1302 GtkTextMark *insert_mark;
1304 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1307 GdkPixbufFormat *pixbuf_format;
1309 image_file_id = g_open (filename, O_RDONLY, 0);
1310 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1311 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1312 TnyMimePart *image_part;
1313 TnyStream *image_stream;
1319 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1320 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1321 mime_type = mime_types[0];
1323 mime_type = "image/unknown";
1325 image_part = tny_platform_factory_new_mime_part
1326 (modest_runtime_get_platform_factory ());
1327 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1329 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1330 g_strfreev (mime_types);
1332 content_id = g_strdup_printf ("%d", priv->last_cid);
1333 tny_mime_part_set_content_id (image_part, content_id);
1334 g_free (content_id);
1337 basename = g_path_get_basename (filename);
1338 tny_mime_part_set_filename (image_part, basename);
1341 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1342 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1343 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1344 priv->attachments = g_list_prepend (priv->attachments, image_part);
1345 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1347 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1348 gtk_widget_show_all (priv->attachments_caption);
1349 } else if (image_file_id == -1) {
1350 close (image_file_id);
1359 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1362 ModestMsgEditWindowPrivate *priv;
1363 GdkColor *new_color;
1364 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1366 #ifdef MODEST_HILDON_VERSION_0
1367 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1370 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1372 #endif /*MODEST_HILDON_VERSION_0*/
1374 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1376 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1381 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1384 ModestMsgEditWindowPrivate *priv;
1385 gint new_size_index;
1386 ModestMsgEditWindow *window;
1389 window = MODEST_MSG_EDIT_WINDOW (userdata);
1390 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1391 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1393 if (gtk_check_menu_item_get_active (menu_item)) {
1396 label = gtk_bin_get_child (GTK_BIN (menu_item));
1398 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1400 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1401 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1402 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1404 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1405 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1406 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1412 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1415 ModestMsgEditWindowPrivate *priv;
1416 gint new_font_index;
1417 ModestMsgEditWindow *window;
1420 window = MODEST_MSG_EDIT_WINDOW (userdata);
1421 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1422 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1424 if (gtk_check_menu_item_get_active (menu_item)) {
1427 label = gtk_bin_get_child (GTK_BIN (menu_item));
1429 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1431 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1432 (gpointer) new_font_index))
1433 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1435 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1436 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1437 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1443 modest_msg_edit_window_set_zoom (ModestWindow *window,
1446 ModestMsgEditWindowPrivate *priv;
1448 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1450 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1451 priv->zoom_level = zoom;
1452 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1456 modest_msg_edit_window_get_zoom (ModestWindow *window)
1458 ModestMsgEditWindowPrivate *priv;
1460 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1462 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1463 return priv->zoom_level;
1467 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1469 ModestWindowPrivate *parent_priv;
1470 GtkRadioAction *zoom_radio_action;
1471 GSList *group, *node;
1473 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1474 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1475 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1477 group = gtk_radio_action_get_group (zoom_radio_action);
1479 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1480 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1484 for (node = group; node != NULL; node = g_slist_next (node)) {
1485 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1486 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1494 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1496 ModestWindowPrivate *parent_priv;
1497 GtkRadioAction *zoom_radio_action;
1498 GSList *group, *node;
1500 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1501 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1502 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1504 group = gtk_radio_action_get_group (zoom_radio_action);
1506 for (node = group; node != NULL; node = g_slist_next (node)) {
1507 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1508 if (node->next != NULL) {
1509 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1512 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1520 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1522 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1523 ModestWindowPrivate *parent_priv;
1524 ModestWindowMgr *mgr;
1525 gboolean is_fullscreen;
1526 GtkAction *fs_toggle_action;
1529 mgr = modest_runtime_get_window_mgr ();
1530 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1532 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1534 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1535 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1536 if (is_fullscreen != active)
1537 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1545 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1547 ModestWindowPrivate *parent_priv;
1548 GtkAction *fs_toggle_action;
1551 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1553 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1554 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1555 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1559 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1562 ModestMsgEditWindowPrivate *priv = NULL;
1563 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1565 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1567 gtk_widget_show (priv->cc_caption);
1569 gtk_widget_hide (priv->cc_caption);
1573 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1576 ModestMsgEditWindowPrivate *priv = NULL;
1577 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1579 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1581 gtk_widget_show (priv->bcc_caption);
1583 gtk_widget_hide (priv->bcc_caption);
1587 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1588 ModestRecptEditor *editor)
1590 ModestMsgEditWindowPrivate *priv;
1592 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1593 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1594 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1596 if (editor == NULL) {
1597 GtkWidget *view_focus;
1598 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1600 /* This code should be kept in sync with ModestRecptEditor. The
1601 textview inside the recpt editor is the one that really gets the
1602 focus. As it's inside a scrolled window, and this one inside the
1603 hbox recpt editor inherits from, we'll need to go up in the
1604 hierarchy to know if the text view is part of the recpt editor
1605 or if it's a different text entry */
1607 if (gtk_widget_get_parent (view_focus)) {
1608 GtkWidget *first_parent;
1610 first_parent = gtk_widget_get_parent (view_focus);
1611 if (gtk_widget_get_parent (first_parent) &&
1612 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1613 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1618 editor = MODEST_RECPT_EDITOR (priv->to_field);
1622 modest_address_book_select_addresses (editor);
1627 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1629 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1631 modest_msg_edit_window_open_addressbook (window, NULL);
1635 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1636 gboolean show_toolbar)
1638 ModestWindowPrivate *parent_priv;
1640 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self));
1641 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1643 /* FIXME: we can not just use the code of
1644 modest_msg_edit_window_setup_toolbar because it has a
1645 mixture of both initialization and creation code. */
1648 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1650 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1654 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1655 TnyHeaderFlags priority_flags)
1657 ModestMsgEditWindowPrivate *priv;
1659 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1661 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1662 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1664 if (priv->priority_flags != priority_flags) {
1666 priv->priority_flags = priority_flags;
1668 switch (priority_flags) {
1669 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1670 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1671 gtk_widget_show (priv->priority_icon);
1673 case TNY_HEADER_FLAG_LOW_PRIORITY:
1674 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1675 gtk_widget_show (priv->priority_icon);
1678 gtk_widget_hide (priv->priority_icon);
1685 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1688 ModestMsgEditWindowPrivate *priv;
1689 gint current_format;
1691 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1693 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1695 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1696 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1698 if (current_format != file_format) {
1699 switch (file_format) {
1700 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1701 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1703 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1707 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1708 response = gtk_dialog_run (GTK_DIALOG (dialog));
1709 gtk_widget_destroy (dialog);
1710 if (response == GTK_RESPONSE_OK)
1711 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1715 update_dimmed (window);
1720 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1723 ModestMsgEditWindowPrivate *priv;
1724 WPTextBufferFormat oldfmt, fmt;
1725 gint old_position = 0;
1729 GdkColor *color = NULL;
1730 gboolean bold, bold_set, italic, italic_set;
1731 gboolean underline, underline_set;
1732 gboolean strikethrough, strikethrough_set;
1733 gboolean position_set;
1734 gboolean font_size_set, font_set, color_set;
1737 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1738 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1740 dialog = hildon_font_selection_dialog_new (NULL, NULL);
1742 /* First we get the currently selected font information */
1743 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
1744 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
1746 switch (oldfmt.text_position) {
1747 case TEXT_POSITION_NORMAL:
1750 case TEXT_POSITION_SUPERSCRIPT:
1758 g_object_set (G_OBJECT (dialog),
1759 "bold", oldfmt.bold != FALSE,
1760 "bold-set", !oldfmt.cs.bold,
1761 "underline", oldfmt.underline != FALSE,
1762 "underline-set", !oldfmt.cs.underline,
1763 "italic", oldfmt.italic != FALSE,
1764 "italic-set", !oldfmt.cs.italic,
1765 "strikethrough", oldfmt.strikethrough != FALSE,
1766 "strikethrough-set", !oldfmt.cs.strikethrough,
1767 "color", &oldfmt.color,
1768 "color-set", !oldfmt.cs.color,
1769 "size", wp_font_size[oldfmt.font_size],
1770 "size-set", !oldfmt.cs.font_size,
1771 "position", old_position,
1772 "position-set", !oldfmt.cs.text_position,
1773 "family", wp_get_font_name (oldfmt.font),
1774 "family-set", !oldfmt.cs.font,
1777 gtk_widget_show_all (dialog);
1778 response = gtk_dialog_run (GTK_DIALOG (dialog));
1779 if (response == GTK_RESPONSE_OK) {
1781 g_object_get( dialog,
1783 "bold-set", &bold_set,
1784 "underline", &underline,
1785 "underline-set", &underline_set,
1787 "italic-set", &italic_set,
1788 "strikethrough", &strikethrough,
1789 "strikethrough-set", &strikethrough_set,
1791 "color-set", &color_set,
1793 "size-set", &font_size_set,
1794 "family", &font_name,
1795 "family-set", &font_set,
1796 "position", &position,
1797 "position-set", &position_set,
1802 gtk_widget_destroy (dialog);
1804 if (response == GTK_RESPONSE_OK) {
1805 memset(&fmt, 0, sizeof(fmt));
1811 fmt.italic = italic;
1812 fmt.cs.italic = TRUE;
1814 if (underline_set) {
1815 fmt.underline = underline;
1816 fmt.cs.underline = TRUE;
1818 if (strikethrough_set) {
1819 fmt.strikethrough = strikethrough;
1820 fmt.cs.strikethrough = TRUE;
1825 ? TEXT_POSITION_NORMAL
1826 : ( ( position == 1 )
1827 ? TEXT_POSITION_SUPERSCRIPT
1828 : TEXT_POSITION_SUBSCRIPT );
1829 fmt.cs.text_position = TRUE;
1833 fmt.cs.color = TRUE;
1835 gdk_color_free(color);
1837 fmt.font = wp_get_font_index(font_name,
1842 if (font_size_set) {
1843 fmt.font_size = wp_get_font_size_index(
1844 font_size, DEFAULT_FONT_SIZE);
1845 fmt.cs.font_size = TRUE;
1847 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
1848 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
1854 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
1856 ModestMsgEditWindowPrivate *priv;
1858 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1859 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1861 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
1863 update_dimmed (window);
1868 update_dimmed (ModestMsgEditWindow *window)
1870 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1871 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1875 gboolean editor_focused;
1877 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1878 editor_focused = gtk_widget_is_focus (priv->msg_body);
1880 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
1881 gtk_action_set_sensitive (action, rich_text && editor_focused);
1882 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1883 gtk_action_set_sensitive (action, rich_text && editor_focused);
1884 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
1885 gtk_action_set_sensitive (action, rich_text && editor_focused);
1886 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1887 gtk_action_set_sensitive (action, rich_text && editor_focused);
1888 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1889 gtk_action_set_sensitive (action, rich_text && editor_focused);
1890 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1891 gtk_action_set_sensitive (action, rich_text && editor_focused);
1892 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
1893 gtk_action_set_sensitive (action, rich_text && editor_focused);
1894 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1895 gtk_action_set_sensitive (action, rich_text && editor_focused);
1896 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1897 gtk_action_set_sensitive (action, rich_text && editor_focused);
1898 widget = priv->font_color_button;
1899 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
1900 widget = priv->font_size_toolitem;
1901 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
1902 widget = priv->font_face_toolitem;
1903 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
1907 setup_insensitive_handlers (ModestMsgEditWindow *window)
1909 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1910 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1913 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1914 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
1915 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
1916 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
1918 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
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/BulletedListMenu");
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");
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/AlignmentLeftMenu");
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/AlignmentCenterMenu");
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/FormatMenu/AlignmentMenu/AlignmentRightMenu");
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, "/MenuBar/AttachmentsMenu/InsertImageMenu");
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/ActionsBold");
1933 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1934 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1935 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1936 widget = priv->font_color_button;
1937 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1938 widget = priv->font_size_toolitem;
1939 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1940 widget = priv->font_face_toolitem;
1941 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
1946 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
1948 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1951 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
1952 gtk_action_set_sensitive (action, can_undo);
1956 msg_body_focus (GtkWidget *focus,
1957 GdkEventFocus *event,
1960 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
1965 to_field_changed (GtkTextBuffer *buffer,
1966 ModestMsgEditWindow *editor)
1968 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
1971 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1972 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
1973 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
1974 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
1978 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
1980 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
1984 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
1986 gboolean rich_text, editor_focused;
1988 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
1989 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1990 editor_focused = gtk_widget_is_focus (priv->msg_body);
1993 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
1994 else if (!editor_focused)
1995 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
1999 reset_modified (ModestMsgEditWindow *editor)
2001 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2002 GtkTextBuffer *buffer;
2004 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2005 gtk_text_buffer_set_modified (buffer, FALSE);
2006 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2007 gtk_text_buffer_set_modified (buffer, FALSE);
2008 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2009 gtk_text_buffer_set_modified (buffer, FALSE);
2010 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2014 is_modified (ModestMsgEditWindow *editor)
2016 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2017 GtkTextBuffer *buffer;
2019 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2020 if (gtk_text_buffer_get_modified (buffer))
2022 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2023 if (gtk_text_buffer_get_modified (buffer))
2025 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2026 if (gtk_text_buffer_get_modified (buffer))
2028 if (gtk_text_buffer_get_modified (priv->text_buffer))
2035 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2037 ModestMsgEditWindowPrivate *priv = NULL;
2039 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2040 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2042 /* check if there's no recipient added */
2043 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2044 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2045 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2046 /* no recipient contents, then select contacts */
2047 modest_msg_edit_window_open_addressbook (window, NULL);
2051 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2053 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2055 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2058 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));