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>
37 #include <tny-vfs-stream.h>
41 #include <modest-account-mgr.h>
42 #include <modest-account-mgr-helpers.h>
44 #include <widgets/modest-msg-edit-window.h>
45 #include <widgets/modest-combo-box.h>
46 #include <widgets/modest-recpt-editor.h>
47 #include <widgets/modest-attachments-view.h>
49 #include <modest-runtime.h>
51 #include "modest-platform.h"
52 #include "modest-icon-names.h"
53 #include "modest-widget-memory.h"
54 #include "modest-window-priv.h"
55 #include "modest-mail-operation.h"
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-address-book.h"
59 #include "modest-text-utils.h"
60 #include <tny-simple-list.h>
61 #include <wptextview.h>
62 #include <wptextbuffer.h>
63 #include "modest-scroll-area.h"
65 #include "modest-hildon-includes.h"
66 #include "widgets/modest-msg-edit-window-ui.h"
67 #include <libgnomevfs/gnome-vfs-mime.h>
70 #define DEFAULT_FONT_SIZE 3
71 #define DEFAULT_FONT 2
72 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
73 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
74 #define DEFAULT_MAIN_VBOX_SPACING 6
75 #define SUBJECT_MAX_LENGTH 1000
77 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
78 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
79 static void modest_msg_edit_window_finalize (GObject *obj);
81 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
82 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
83 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
84 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
85 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
86 static void reset_modified (ModestMsgEditWindow *editor);
87 static gboolean is_modified (ModestMsgEditWindow *editor);
89 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
90 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
91 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
92 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
93 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
94 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
96 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
98 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
100 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
101 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
102 GdkEventWindowState *event,
104 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
105 ModestRecptEditor *editor);
106 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
107 ModestMsgEditWindow *window);
109 /* ModestWindow methods implementation */
110 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
111 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
112 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
113 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
114 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
115 gboolean show_toolbar);
116 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
118 ModestMsgEditWindow *window);
119 static void update_window_title (ModestMsgEditWindow *window);
120 static void update_dimmed (ModestMsgEditWindow *window);
123 /* list my signals */
130 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
131 struct _ModestMsgEditWindowPrivate {
133 GtkWidget *header_box;
135 ModestPairList *from_field_protos;
136 GtkWidget *from_field;
140 GtkWidget *bcc_field;
141 GtkWidget *subject_field;
142 GtkWidget *attachments_view;
143 GtkWidget *priority_icon;
144 GtkWidget *add_attachment_button;
146 GtkWidget *cc_caption;
147 GtkWidget *bcc_caption;
148 GtkWidget *attachments_caption;
150 GtkTextBuffer *text_buffer;
152 GtkWidget *font_size_toolitem;
153 GtkWidget *font_face_toolitem;
154 GtkWidget *font_color_button;
155 GSList *font_items_group;
156 GtkWidget *font_tool_button_label;
157 GSList *size_items_group;
158 GtkWidget *size_tool_button_label;
165 TnyHeaderFlags priority_flags;
169 gulong clipboard_change_handler_id;
174 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
175 MODEST_TYPE_MSG_EDIT_WINDOW, \
176 ModestMsgEditWindowPrivate))
178 static GtkWindowClass *parent_class = NULL;
180 /* uncomment the following if you have defined any signals */
181 /* static guint signals[LAST_SIGNAL] = {0}; */
184 modest_msg_edit_window_get_type (void)
186 static GType my_type = 0;
188 static const GTypeInfo my_info = {
189 sizeof(ModestMsgEditWindowClass),
190 NULL, /* base init */
191 NULL, /* base finalize */
192 (GClassInitFunc) modest_msg_edit_window_class_init,
193 NULL, /* class finalize */
194 NULL, /* class data */
195 sizeof(ModestMsgEditWindow),
197 (GInstanceInitFunc) modest_msg_edit_window_init,
200 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
201 "ModestMsgEditWindow",
204 wp_text_buffer_library_init ();
210 save_state (ModestWindow *self)
212 modest_widget_memory_save (modest_runtime_get_conf(),
213 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
218 restore_settings (ModestMsgEditWindow *self)
220 modest_widget_memory_restore (modest_runtime_get_conf(),
221 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
226 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
228 GObjectClass *gobject_class;
229 ModestWindowClass *modest_window_class;
230 gobject_class = (GObjectClass*) klass;
231 modest_window_class = (ModestWindowClass*) klass;
233 parent_class = g_type_class_peek_parent (klass);
234 gobject_class->finalize = modest_msg_edit_window_finalize;
236 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
237 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
238 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
239 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
240 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
242 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
244 modest_window_class->save_state_func = save_state;
248 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
250 ModestMsgEditWindowPrivate *priv;
251 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
253 priv->msg_body = NULL;
254 priv->from_field = NULL;
255 priv->to_field = NULL;
256 priv->cc_field = NULL;
257 priv->bcc_field = NULL;
258 priv->subject_field = NULL;
259 priv->attachments = NULL;
261 priv->zoom_level = 1.0;
263 priv->cc_caption = NULL;
264 priv->bcc_caption = NULL;
266 priv->priority_flags = 0;
268 priv->draft_msg = NULL;
269 priv->clipboard_change_handler_id = 0;
273 /* FIXME: this is a dup from the one in gtk/ */
276 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
278 static ModestPairList*
279 get_transports (void)
281 GSList *transports = NULL;
283 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
284 GSList *accounts = modest_account_mgr_account_names (account_mgr,
285 TRUE /* only enabled accounts. */);
287 GSList *cursor = accounts;
289 const gchar *account_name = cursor->data;
290 gchar *from_string = NULL;
292 from_string = modest_account_mgr_get_from_string (account_mgr,
296 if (from_string && account_name) {
297 gchar *name = g_strdup (account_name);
298 ModestPair *pair = modest_pair_new ((gpointer) name,
299 (gpointer) from_string , TRUE);
300 transports = g_slist_prepend (transports, pair);
303 cursor = cursor->next;
305 g_slist_free (accounts);
311 init_window (ModestMsgEditWindow *obj)
313 GtkWidget *from_caption, *to_caption, *subject_caption;
314 GtkWidget *main_vbox;
315 ModestMsgEditWindowPrivate *priv;
317 GtkSizeGroup *size_group;
319 GtkWidget *scroll_area;
320 GtkWidget *subject_box;
321 GtkWidget *attachment_icon;
323 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
325 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
327 /* Note: This ModestPairList* must exist for as long as the combo
328 * that uses it, because the ModestComboBox uses the ID opaquely,
329 * so it can't know how to manage its memory. */
330 priv->from_field_protos = get_transports ();
332 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
334 priv->to_field = modest_recpt_editor_new ();
335 priv->cc_field = modest_recpt_editor_new ();
336 priv->bcc_field = modest_recpt_editor_new ();
337 subject_box = gtk_hbox_new (FALSE, 0);
338 priv->priority_icon = gtk_image_new ();
339 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
340 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
341 g_object_set (G_OBJECT (priv->subject_field), "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
342 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
343 priv->add_attachment_button = gtk_button_new ();
344 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
345 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
346 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
347 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
348 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
349 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
350 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
351 priv->attachments_view = modest_attachments_view_new (NULL);
353 priv->header_box = gtk_vbox_new (FALSE, 0);
355 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
356 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
357 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
358 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
359 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
360 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
361 g_object_unref (size_group);
363 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
364 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
365 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
366 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
367 gtk_size_group_add_widget (size_group, priv->subject_field);
368 gtk_size_group_add_widget (size_group, priv->attachments_view);
369 g_object_unref (size_group);
371 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
372 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
373 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
374 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
375 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
376 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
377 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
380 priv->msg_body = wp_text_view_new ();
381 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
382 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
383 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
384 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
385 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
386 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
388 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
389 G_CALLBACK (text_buffer_refresh_attributes), obj);
390 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
391 G_CALLBACK (text_buffer_delete_range), obj);
392 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
393 G_CALLBACK (text_buffer_can_undo), obj);
394 g_signal_connect (G_OBJECT (obj), "window-state-event",
395 G_CALLBACK (modest_msg_edit_window_window_state_event),
397 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
398 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
399 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
400 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
401 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
402 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
404 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
405 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
407 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
408 G_CALLBACK (msg_body_focus), obj);
409 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
410 G_CALLBACK (msg_body_focus), obj);
411 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
412 "changed", G_CALLBACK (recpt_field_changed), obj);
413 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
414 "changed", G_CALLBACK (recpt_field_changed), obj);
415 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
416 "changed", G_CALLBACK (recpt_field_changed), obj);
417 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
418 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
420 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
421 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
422 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
424 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
426 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
427 frame = gtk_frame_new (NULL);
428 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
430 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
431 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
432 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
434 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
435 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
436 gtk_widget_hide (priv->cc_caption);
438 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
439 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
440 gtk_widget_hide (priv->bcc_caption);
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)));
449 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
450 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
456 modest_msg_edit_window_finalize (GObject *obj)
458 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
461 if (priv->clipboard_change_handler_id > 0) {
462 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
463 priv->clipboard_change_handler_id = 0;
466 /* This had to stay alive for as long as the combobox that used it: */
467 modest_pair_list_free (priv->from_field_protos);
469 G_OBJECT_CLASS(parent_class)->finalize (obj);
473 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
475 GtkWidget *close_dialog;
476 ModestMsgEditWindowPrivate *priv;
479 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
480 modest_window_save_state (MODEST_WINDOW (self));
481 if (is_modified (self)) {
482 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
483 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
484 gtk_widget_destroy (close_dialog);
486 if (response != GTK_RESPONSE_CANCEL) {
487 modest_ui_actions_on_save_to_drafts (NULL, self);
490 /* /\* remove old message from drafts *\/ */
491 /* if (priv->draft_msg) { */
492 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
493 /* TnyAccount *account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(), */
495 /* TNY_ACCOUNT_TYPE_STORE); */
496 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
497 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
498 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
499 /* tny_folder_remove_msg (folder, header, NULL); */
500 /* g_object_unref (folder); */
501 /* g_object_unref (header); */
502 /* g_object_unref (priv->draft_msg); */
503 /* priv->draft_msg = NULL; */
505 gtk_widget_destroy (GTK_WIDGET (self));
511 menubar_to_menu (GtkUIManager *ui_manager)
513 GtkWidget *main_menu;
517 /* Create new main menu */
518 main_menu = gtk_menu_new();
520 /* Get the menubar from the UI manager */
521 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
523 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
527 menu = GTK_WIDGET (iter->data);
528 gtk_widget_reparent(menu, main_menu);
530 iter = g_list_next (iter);
537 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
540 const gchar *to, *cc, *bcc, *subject;
542 ModestMsgEditWindowPrivate *priv;
545 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
546 g_return_if_fail (TNY_IS_MSG (msg));
548 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
550 header = tny_msg_get_header (msg);
551 to = tny_header_get_to (header);
552 cc = tny_header_get_cc (header);
553 bcc = tny_header_get_bcc (header);
554 subject = tny_header_get_subject (header);
557 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
559 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
561 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
563 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
565 update_window_title (self);
567 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
568 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
569 body = modest_tny_msg_get_body (msg, TRUE);
571 if ((body == NULL)||(body[0] == '\0')) {
573 body = modest_text_utils_convert_to_html ("");
575 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
576 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
579 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
582 /* Get the default format required from configuration */
583 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
584 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
587 /* Set the default focus depending on having already a To: field or not */
588 if ((!to)||(*to == '\0')) {
589 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
591 gtk_widget_grab_focus (priv->msg_body);
594 /* TODO: lower priority, select in the From: combo to the
595 value that comes from msg <- not sure, should it be
598 /* Add attachments to the view */
599 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
600 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
601 if (priv->attachments == NULL) {
602 gtk_widget_hide (priv->attachments_caption);
604 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
605 gtk_widget_show_all (priv->attachments_caption);
608 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
609 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
611 reset_modified (self);
613 update_dimmed (self);
614 text_buffer_can_undo (priv->text_buffer, FALSE, self);
616 priv->draft_msg = msg;
620 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
623 GList *item_children, *node;
624 GtkWidget *bin_child;
626 bin_child = gtk_bin_get_child (GTK_BIN(item));
628 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
630 for (node = item_children; node != NULL; node = g_list_next (node)) {
631 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
632 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
635 g_list_free (item_children);
639 menu_tool_button_dont_expand (GtkMenuToolButton *item)
642 GList *item_children, *node;
644 box = gtk_bin_get_child (GTK_BIN (item));
645 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
646 item_children = gtk_container_get_children (GTK_CONTAINER (box));
648 for (node = item_children; node != NULL; node = g_list_next (node)) {
649 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
650 if (GTK_IS_TOGGLE_BUTTON (node->data))
651 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
652 else if (GTK_IS_BUTTON (node->data))
653 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
655 g_list_free (item_children);
660 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
662 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
663 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
664 GtkWidget *placeholder;
665 GtkWidget *tool_item;
670 GtkWidget *sizes_menu;
671 GtkWidget *fonts_menu;
672 GSList *radio_group = NULL;
677 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
678 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
680 /* should we hide the toolbar? */
681 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
682 gtk_widget_hide (parent_priv->toolbar);
684 /* Font color placeholder */
685 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
686 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
689 tool_item = GTK_WIDGET (gtk_tool_item_new ());
690 priv->font_color_button = hildon_color_button_new ();
691 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
692 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
693 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
694 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
695 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
696 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
697 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
699 /* Font size and face placeholder */
700 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
701 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
703 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
704 priv->size_tool_button_label = gtk_label_new (NULL);
705 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
706 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
707 size_text,"</span>", NULL);
708 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
710 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
711 sizes_menu = gtk_menu_new ();
712 priv->size_items_group = NULL;
714 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
715 GtkWidget *size_menu_item;
717 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
718 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
719 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
720 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
721 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
722 gtk_widget_show (size_menu_item);
724 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
728 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
729 GtkWidget *item = (GtkWidget *) node->data;
730 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
734 priv->size_items_group = g_slist_reverse (priv->size_items_group);
735 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
736 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
737 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
738 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
739 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
740 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
741 priv->font_size_toolitem = tool_item;
744 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
745 priv->font_tool_button_label = gtk_label_new (NULL);
746 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
747 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
749 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
750 fonts_menu = gtk_menu_new ();
751 priv->font_items_group = NULL;
753 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
754 GtkWidget *font_menu_item;
755 GtkWidget *child_label;
757 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
758 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
759 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
760 wp_get_font_name (font_index), "</span>", NULL);
761 gtk_label_set_markup (GTK_LABEL (child_label), markup);
764 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
765 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
766 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
767 gtk_widget_show (font_menu_item);
769 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
772 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
773 GtkWidget *item = (GtkWidget *) node->data;
774 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
777 priv->font_items_group = g_slist_reverse (priv->font_items_group);
778 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
779 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
780 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
781 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
782 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
783 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
784 priv->font_face_toolitem = tool_item;
786 /* Set expand and homogeneous for remaining items */
787 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
788 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
789 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
790 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
791 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
792 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
793 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
794 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
795 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
803 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
806 ModestWindowPrivate *parent_priv;
807 ModestMsgEditWindowPrivate *priv;
808 GtkActionGroup *action_group;
809 GError *error = NULL;
810 GdkPixbuf *window_icon = NULL;
813 gboolean prefer_formatted;
816 g_return_val_if_fail (msg, NULL);
818 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
820 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
821 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
823 parent_priv->ui_manager = gtk_ui_manager_new();
824 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
825 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
827 /* Add common actions */
828 gtk_action_group_add_actions (action_group,
829 modest_msg_edit_action_entries,
830 G_N_ELEMENTS (modest_msg_edit_action_entries),
832 gtk_action_group_add_toggle_actions (action_group,
833 modest_msg_edit_toggle_action_entries,
834 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
836 gtk_action_group_add_radio_actions (action_group,
837 modest_msg_edit_alignment_radio_action_entries,
838 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
840 G_CALLBACK (modest_ui_actions_on_change_justify),
842 gtk_action_group_add_radio_actions (action_group,
843 modest_msg_edit_zoom_action_entries,
844 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
846 G_CALLBACK (modest_ui_actions_on_change_zoom),
848 gtk_action_group_add_radio_actions (action_group,
849 modest_msg_edit_priority_action_entries,
850 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
852 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
854 gtk_action_group_add_radio_actions (action_group,
855 modest_msg_edit_file_format_action_entries,
856 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
857 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
858 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
860 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
861 g_object_unref (action_group);
863 /* Load the UI definition */
864 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml", &error);
866 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
867 g_clear_error (&error);
870 /* Add accelerators */
871 gtk_window_add_accel_group (GTK_WINDOW (obj),
872 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
875 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
876 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
879 init_window (MODEST_MSG_EDIT_WINDOW(obj));
881 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
883 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
885 g_signal_connect (G_OBJECT(obj), "delete-event",
886 G_CALLBACK(on_delete_event), obj);
888 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
890 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
892 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
894 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
896 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
898 /* Set window icon */
899 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
900 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
902 /* Dim at start clipboard actions */
903 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
904 gtk_action_set_sensitive (action, FALSE);
905 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
906 gtk_action_set_sensitive (action, FALSE);
908 /* set initial state of cc and bcc */
909 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
910 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
911 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
912 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
913 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
914 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
916 /* Setup the file format */
917 conf = modest_runtime_get_conf ();
918 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
920 g_clear_error (&error);
921 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
923 file_format = (prefer_formatted) ?
924 MODEST_FILE_FORMAT_FORMATTED_TEXT :
925 MODEST_FILE_FORMAT_PLAIN_TEXT;
926 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
928 return (ModestWindow*) obj;
932 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
934 GString **string_buffer = (GString **) user_data;
936 *string_buffer = g_string_append (*string_buffer, buffer);
942 * @result: A new string which should be freed with g_free().
945 get_formatted_data (ModestMsgEditWindow *edit_window)
947 ModestMsgEditWindowPrivate *priv;
948 GString *string_buffer = g_string_new ("");
950 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
952 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
954 return g_string_free (string_buffer, FALSE);
959 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
962 const gchar *account_name;
963 ModestMsgEditWindowPrivate *priv;
965 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
967 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
969 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
970 g_return_val_if_fail (account_name, NULL);
973 /* don't free these (except from) */
974 data = g_slice_new0 (MsgData);
975 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
977 data->account_name = g_strdup (account_name);
978 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
979 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
980 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
981 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
982 if (priv->draft_msg) {
983 data->draft_msg = g_object_ref (priv->draft_msg);
985 data->draft_msg = NULL;
988 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
990 gtk_text_buffer_get_bounds (buf, &b, &e);
991 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
993 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
994 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
996 data->html_body = NULL;
998 data->attachments = priv->attachments; /* TODO: copy and free ? */
999 data->priority_flags = priv->priority_flags;
1004 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1006 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1009 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1017 g_free (data->subject);
1018 g_free (data->plain_body);
1019 g_free (data->html_body);
1020 if (data->draft_msg != NULL) {
1021 g_object_unref (data->draft_msg);
1022 data->draft_msg = NULL;
1024 g_free (data->account_name);
1026 /* TODO: Free data->attachments? */
1028 g_slice_free (MsgData, data);
1032 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1035 ModestMsgEditWindowPrivate *priv = NULL;
1036 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1038 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1040 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1042 return MODEST_MSG_EDIT_FORMAT_HTML;
1044 return MODEST_MSG_EDIT_FORMAT_TEXT;
1048 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1049 ModestMsgEditFormat format)
1051 ModestMsgEditWindowPrivate *priv;
1053 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1054 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1057 case MODEST_MSG_EDIT_FORMAT_HTML:
1058 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1060 case MODEST_MSG_EDIT_FORMAT_TEXT:
1061 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1064 g_return_if_reached ();
1068 ModestMsgEditFormatState *
1069 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1071 ModestMsgEditFormatState *format_state = NULL;
1072 ModestMsgEditWindowPrivate *priv;
1073 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1075 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1076 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1078 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1080 format_state = g_new0 (ModestMsgEditFormatState, 1);
1081 format_state->bold = buffer_format->bold&0x1;
1082 format_state->italics = buffer_format->italic&0x1;
1083 format_state->bullet = buffer_format->bullet&0x1;
1084 format_state->color = buffer_format->color;
1085 format_state->font_size = buffer_format->font_size;
1086 format_state->font_family = wp_get_font_name (buffer_format->font);
1087 format_state->justification = buffer_format->justification;
1088 g_free (buffer_format);
1090 return format_state;
1095 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1096 const ModestMsgEditFormatState *format_state)
1098 ModestMsgEditWindowPrivate *priv;
1099 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1100 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1101 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1102 g_return_if_fail (format_state != NULL);
1104 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1105 gtk_widget_grab_focus (priv->msg_body);
1106 buffer_format->bold = (format_state->bold != FALSE);
1107 buffer_format->italic = (format_state->italics != FALSE);
1108 buffer_format->color = format_state->color;
1109 buffer_format->font_size = format_state->font_size;
1110 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1111 buffer_format->justification = format_state->justification;
1112 buffer_format->bullet = format_state->bullet;
1114 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1116 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1117 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1118 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1119 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1120 buffer_format->cs.font = (buffer_format->font != current_format->font);
1121 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1122 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1124 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1125 if (buffer_format->cs.bold) {
1126 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1128 if (buffer_format->cs.italic) {
1129 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1131 if (buffer_format->cs.color) {
1132 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1134 if (buffer_format->cs.font_size) {
1135 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1137 if (buffer_format->cs.justification) {
1138 switch (buffer_format->justification) {
1139 case GTK_JUSTIFY_LEFT:
1140 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1142 case GTK_JUSTIFY_CENTER:
1143 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1145 case GTK_JUSTIFY_RIGHT:
1146 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1153 if (buffer_format->cs.font) {
1154 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1156 if (buffer_format->cs.bullet) {
1157 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
1159 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1160 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1162 g_free (current_format);
1167 toggle_action_set_active_block_notify (GtkToggleAction *action,
1170 GSList *proxies = NULL;
1172 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1173 proxies != NULL; proxies = g_slist_next (proxies)) {
1174 GtkWidget *widget = (GtkWidget *) proxies->data;
1175 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1178 gtk_toggle_action_set_active (action, value);
1180 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1181 proxies != NULL; proxies = g_slist_next (proxies)) {
1182 GtkWidget *widget = (GtkWidget *) proxies->data;
1183 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1188 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1190 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1192 ModestWindowPrivate *parent_priv;
1193 ModestMsgEditWindowPrivate *priv;
1194 GtkWidget *new_size_menuitem;
1195 GtkWidget *new_font_menuitem;
1197 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1198 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1200 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1201 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1202 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1203 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1205 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1206 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1207 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1210 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1212 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1213 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1215 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1216 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1218 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1219 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1221 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1222 G_CALLBACK (modest_msg_edit_window_color_button_change),
1224 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1225 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1226 G_CALLBACK (modest_msg_edit_window_color_button_change),
1229 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1230 buffer_format->font_size))->data);
1231 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1235 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1236 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1237 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1239 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1240 G_CALLBACK (modest_msg_edit_window_size_change),
1242 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1243 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1244 G_CALLBACK (modest_msg_edit_window_size_change),
1248 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1249 buffer_format->font))->data);
1250 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1254 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1255 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1256 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1258 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1259 G_CALLBACK (modest_msg_edit_window_font_change),
1261 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1262 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1263 G_CALLBACK (modest_msg_edit_window_font_change),
1267 g_free (buffer_format);
1273 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1276 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1277 ModestMsgEditWindowPrivate *priv;
1278 GtkWidget *dialog = NULL;
1280 const GdkColor *new_color = NULL;
1282 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1283 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1285 #ifdef MODEST_HILDON_VERSION_0
1286 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1287 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1289 dialog = hildon_color_chooser_new ();
1290 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1291 #endif /*MODEST_HILDON_VERSION_0*/
1292 g_free (buffer_format);
1294 response = gtk_dialog_run (GTK_DIALOG (dialog));
1296 case GTK_RESPONSE_OK: {
1297 #ifdef MODEST_HILDON_VERSION_0
1298 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1301 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1303 #endif /*MODEST_HILDON_VERSION_0*/
1310 gtk_widget_destroy (dialog);
1312 if (new_color != NULL)
1313 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1318 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1321 ModestMsgEditWindowPrivate *priv;
1322 GtkWidget *dialog = NULL;
1324 GdkColor *old_color = NULL;
1325 const GdkColor *new_color = NULL;
1327 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1328 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1330 #ifdef MODEST_HILDON_VERSION_0
1331 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1332 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1334 dialog = hildon_color_chooser_new ();
1335 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1336 #endif /*MODEST_HILDON_VERSION_9*/
1338 response = gtk_dialog_run (GTK_DIALOG (dialog));
1340 case GTK_RESPONSE_OK: {
1341 #ifdef MODEST_HILDON_VERSION_0
1342 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1345 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1347 #endif /*MODEST_HILDON_VERSION_0*/
1353 gtk_widget_destroy (dialog);
1355 if (new_color != NULL)
1356 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1361 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1364 ModestMsgEditWindowPrivate *priv;
1365 GtkWidget *dialog = NULL;
1367 gchar *filename = NULL;
1369 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1371 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1373 response = gtk_dialog_run (GTK_DIALOG (dialog));
1375 case GTK_RESPONSE_OK:
1376 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1381 gtk_widget_destroy (dialog);
1384 GdkPixbuf *pixbuf = NULL;
1385 GtkTextIter position;
1386 GtkTextMark *insert_mark;
1388 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1391 GdkPixbufFormat *pixbuf_format;
1393 image_file_id = g_open (filename, O_RDONLY, 0);
1394 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1395 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1396 TnyMimePart *image_part;
1397 TnyStream *image_stream;
1403 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1404 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1405 mime_type = mime_types[0];
1407 mime_type = "image/unknown";
1409 image_part = tny_platform_factory_new_mime_part
1410 (modest_runtime_get_platform_factory ());
1411 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1413 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1414 g_strfreev (mime_types);
1416 content_id = g_strdup_printf ("%d", priv->last_cid);
1417 tny_mime_part_set_content_id (image_part, content_id);
1418 g_free (content_id);
1421 basename = g_path_get_basename (filename);
1422 tny_mime_part_set_filename (image_part, basename);
1425 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1426 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1427 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1428 priv->attachments = g_list_prepend (priv->attachments, image_part);
1429 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1431 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1432 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1433 gtk_widget_show_all (priv->attachments_caption);
1434 } else if (image_file_id == -1) {
1435 close (image_file_id);
1444 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1447 ModestMsgEditWindowPrivate *priv;
1448 GtkWidget *dialog = NULL;
1450 gchar *uri = NULL, *filename = NULL;
1452 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1454 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1456 response = gtk_dialog_run (GTK_DIALOG (dialog));
1458 case GTK_RESPONSE_OK:
1459 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
1460 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1465 gtk_widget_destroy (dialog);
1469 GnomeVFSHandle *handle = NULL;
1470 GnomeVFSResult result;
1472 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1473 if (result == GNOME_VFS_OK) {
1474 TnyMimePart *mime_part;
1476 const gchar *mime_type = NULL;
1479 GnomeVFSFileInfo info;
1481 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1482 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1483 mime_part = tny_platform_factory_new_mime_part
1484 (modest_runtime_get_platform_factory ());
1485 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1487 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1489 content_id = g_strdup_printf ("%d", priv->last_cid);
1490 tny_mime_part_set_content_id (mime_part, content_id);
1491 g_free (content_id);
1494 basename = g_path_get_basename (filename);
1495 tny_mime_part_set_filename (mime_part, basename);
1498 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1499 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1501 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1502 gtk_widget_show_all (priv->attachments_caption);
1503 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1510 modest_msg_edit_window_attach_file_noninteractive (
1511 ModestMsgEditWindow *window,
1515 ModestMsgEditWindowPrivate *priv;
1517 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1522 file_id = g_open (filename, O_RDONLY, 0);
1523 if (file_id != -1) {
1524 TnyMimePart *mime_part;
1526 const gchar *mime_type;
1530 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1531 mime_part = tny_platform_factory_new_mime_part
1532 (modest_runtime_get_platform_factory ());
1533 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1535 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1537 content_id = g_strdup_printf ("%d", priv->last_cid);
1538 tny_mime_part_set_content_id (mime_part, content_id);
1539 g_free (content_id);
1542 basename = g_path_get_basename (filename);
1543 tny_mime_part_set_filename (mime_part, basename);
1546 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1547 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1549 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1550 gtk_widget_show_all (priv->attachments_caption);
1551 } else if (file_id == -1) {
1558 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1561 ModestMsgEditWindowPrivate *priv;
1562 gboolean clean_list = FALSE;
1564 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1565 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1567 if (att_list == NULL) {
1568 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1572 if (att_list == NULL) {
1573 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1575 GtkWidget *confirmation_dialog = NULL;
1576 gboolean dialog_response;
1578 if (att_list->next == NULL) {
1579 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1580 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1581 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1584 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1586 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1587 gtk_widget_destroy (confirmation_dialog);
1588 if (!dialog_response) {
1590 g_list_free (att_list);
1593 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1595 for (node = att_list; node != NULL; node = g_list_next (node)) {
1596 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1597 const gchar *att_id;
1598 priv->attachments = g_list_remove (priv->attachments, mime_part);
1600 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1602 if (priv->attachments == NULL)
1603 gtk_widget_hide (priv->attachments_caption);
1604 att_id = tny_mime_part_get_content_id (mime_part);
1606 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1608 g_object_unref (mime_part);
1609 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1614 g_list_free (att_list);
1618 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1621 ModestMsgEditWindowPrivate *priv;
1622 GdkColor *new_color;
1623 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1625 #ifdef MODEST_HILDON_VERSION_0
1626 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1629 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1631 #endif /*MODEST_HILDON_VERSION_0*/
1633 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1635 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1640 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1643 ModestMsgEditWindowPrivate *priv;
1644 gint new_size_index;
1645 ModestMsgEditWindow *window;
1648 window = MODEST_MSG_EDIT_WINDOW (userdata);
1649 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1650 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1652 if (gtk_check_menu_item_get_active (menu_item)) {
1654 WPTextBufferFormat format;
1656 memset (&format, 0, sizeof (format));
1657 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1659 label = gtk_bin_get_child (GTK_BIN (menu_item));
1661 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1662 format.cs.font_size = TRUE;
1663 format.cs.text_position = TRUE;
1664 format.cs.font = TRUE;
1665 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1666 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1668 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1669 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1670 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1672 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1673 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1674 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1680 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1683 ModestMsgEditWindowPrivate *priv;
1684 gint new_font_index;
1685 ModestMsgEditWindow *window;
1688 window = MODEST_MSG_EDIT_WINDOW (userdata);
1689 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1690 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1692 if (gtk_check_menu_item_get_active (menu_item)) {
1695 label = gtk_bin_get_child (GTK_BIN (menu_item));
1697 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1699 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1700 (gpointer) new_font_index))
1701 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1703 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1704 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1705 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1711 modest_msg_edit_window_set_zoom (ModestWindow *window,
1714 ModestMsgEditWindowPrivate *priv;
1716 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1718 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1719 priv->zoom_level = zoom;
1720 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1724 modest_msg_edit_window_get_zoom (ModestWindow *window)
1726 ModestMsgEditWindowPrivate *priv;
1728 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1730 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1731 return priv->zoom_level;
1735 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1737 ModestWindowPrivate *parent_priv;
1738 GtkRadioAction *zoom_radio_action;
1739 GSList *group, *node;
1741 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1742 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1743 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1745 group = gtk_radio_action_get_group (zoom_radio_action);
1747 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1748 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1752 for (node = group; node != NULL; node = g_slist_next (node)) {
1753 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1754 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1762 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1764 ModestWindowPrivate *parent_priv;
1765 GtkRadioAction *zoom_radio_action;
1766 GSList *group, *node;
1768 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1769 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1770 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1772 group = gtk_radio_action_get_group (zoom_radio_action);
1774 for (node = group; node != NULL; node = g_slist_next (node)) {
1775 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1776 if (node->next != NULL) {
1777 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1780 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1788 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1790 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1791 ModestWindowPrivate *parent_priv;
1792 ModestWindowMgr *mgr;
1793 gboolean is_fullscreen;
1794 GtkAction *fs_toggle_action;
1797 mgr = modest_runtime_get_window_mgr ();
1798 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1800 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1802 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1803 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1804 if (is_fullscreen != active)
1805 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1813 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1815 ModestWindowPrivate *parent_priv;
1816 GtkAction *fs_toggle_action;
1819 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1821 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1822 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1823 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1827 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1830 ModestMsgEditWindowPrivate *priv = NULL;
1831 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1833 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1834 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1836 gtk_widget_show (priv->cc_caption);
1838 gtk_widget_hide (priv->cc_caption);
1839 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1843 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1846 ModestMsgEditWindowPrivate *priv = NULL;
1847 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1849 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1850 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1852 gtk_widget_show (priv->bcc_caption);
1854 gtk_widget_hide (priv->bcc_caption);
1855 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
1859 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1860 ModestRecptEditor *editor)
1862 ModestMsgEditWindowPrivate *priv;
1864 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1865 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1866 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1868 if (editor == NULL) {
1869 GtkWidget *view_focus;
1870 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1872 /* This code should be kept in sync with ModestRecptEditor. The
1873 textview inside the recpt editor is the one that really gets the
1874 focus. As it's inside a scrolled window, and this one inside the
1875 hbox recpt editor inherits from, we'll need to go up in the
1876 hierarchy to know if the text view is part of the recpt editor
1877 or if it's a different text entry */
1879 if (gtk_widget_get_parent (view_focus)) {
1880 GtkWidget *first_parent;
1882 first_parent = gtk_widget_get_parent (view_focus);
1883 if (gtk_widget_get_parent (first_parent) &&
1884 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1885 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1890 editor = MODEST_RECPT_EDITOR (priv->to_field);
1894 modest_address_book_select_addresses (editor);
1899 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1901 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1903 modest_msg_edit_window_open_addressbook (window, NULL);
1907 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1908 gboolean show_toolbar)
1910 ModestWindowPrivate *parent_priv;
1912 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1913 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1915 /* FIXME: we can not just use the code of
1916 modest_msg_edit_window_setup_toolbar because it has a
1917 mixture of both initialization and creation code. */
1920 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1922 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1926 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1927 TnyHeaderFlags priority_flags)
1929 ModestMsgEditWindowPrivate *priv;
1931 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1933 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1934 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1936 if (priv->priority_flags != priority_flags) {
1938 priv->priority_flags = priority_flags;
1940 switch (priority_flags) {
1941 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1942 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1943 gtk_widget_show (priv->priority_icon);
1945 case TNY_HEADER_FLAG_LOW_PRIORITY:
1946 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1947 gtk_widget_show (priv->priority_icon);
1950 gtk_widget_hide (priv->priority_icon);
1957 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1960 ModestMsgEditWindowPrivate *priv;
1961 gint current_format;
1963 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1965 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1967 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1968 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1970 if (current_format != file_format) {
1971 switch (file_format) {
1972 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1973 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1975 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1979 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1980 response = gtk_dialog_run (GTK_DIALOG (dialog));
1981 gtk_widget_destroy (dialog);
1982 if (response == GTK_RESPONSE_OK)
1983 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1987 update_dimmed (window);
1992 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1995 ModestMsgEditWindowPrivate *priv;
1996 WPTextBufferFormat oldfmt, fmt;
1997 gint old_position = 0;
2001 GdkColor *color = NULL;
2002 gboolean bold, bold_set, italic, italic_set;
2003 gboolean underline, underline_set;
2004 gboolean strikethrough, strikethrough_set;
2005 gboolean position_set;
2006 gboolean font_size_set, font_set, color_set;
2009 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2010 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2012 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2014 /* First we get the currently selected font information */
2015 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2016 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2018 switch (oldfmt.text_position) {
2019 case TEXT_POSITION_NORMAL:
2022 case TEXT_POSITION_SUPERSCRIPT:
2030 g_object_set (G_OBJECT (dialog),
2031 "bold", oldfmt.bold != FALSE,
2032 "bold-set", !oldfmt.cs.bold,
2033 "underline", oldfmt.underline != FALSE,
2034 "underline-set", !oldfmt.cs.underline,
2035 "italic", oldfmt.italic != FALSE,
2036 "italic-set", !oldfmt.cs.italic,
2037 "strikethrough", oldfmt.strikethrough != FALSE,
2038 "strikethrough-set", !oldfmt.cs.strikethrough,
2039 "color", &oldfmt.color,
2040 "color-set", !oldfmt.cs.color,
2041 "size", wp_font_size[oldfmt.font_size],
2042 "size-set", !oldfmt.cs.font_size,
2043 "position", old_position,
2044 "position-set", !oldfmt.cs.text_position,
2045 "family", wp_get_font_name (oldfmt.font),
2046 "family-set", !oldfmt.cs.font,
2049 gtk_widget_show_all (dialog);
2050 response = gtk_dialog_run (GTK_DIALOG (dialog));
2051 if (response == GTK_RESPONSE_OK) {
2053 g_object_get( dialog,
2055 "bold-set", &bold_set,
2056 "underline", &underline,
2057 "underline-set", &underline_set,
2059 "italic-set", &italic_set,
2060 "strikethrough", &strikethrough,
2061 "strikethrough-set", &strikethrough_set,
2063 "color-set", &color_set,
2065 "size-set", &font_size_set,
2066 "family", &font_name,
2067 "family-set", &font_set,
2068 "position", &position,
2069 "position-set", &position_set,
2074 if (response == GTK_RESPONSE_OK) {
2075 memset(&fmt, 0, sizeof(fmt));
2081 fmt.italic = italic;
2082 fmt.cs.italic = TRUE;
2084 if (underline_set) {
2085 fmt.underline = underline;
2086 fmt.cs.underline = TRUE;
2088 if (strikethrough_set) {
2089 fmt.strikethrough = strikethrough;
2090 fmt.cs.strikethrough = TRUE;
2095 ? TEXT_POSITION_NORMAL
2096 : ( ( position == 1 )
2097 ? TEXT_POSITION_SUPERSCRIPT
2098 : TEXT_POSITION_SUBSCRIPT );
2099 fmt.cs.text_position = TRUE;
2103 fmt.cs.color = TRUE;
2106 fmt.font = wp_get_font_index(font_name,
2111 if (font_size_set) {
2112 fmt.font_size = wp_get_font_size_index(
2113 font_size, DEFAULT_FONT_SIZE);
2114 fmt.cs.font_size = TRUE;
2116 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2118 gtk_widget_destroy (dialog);
2120 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2124 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2126 ModestMsgEditWindowPrivate *priv;
2128 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2129 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2131 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2133 update_dimmed (window);
2138 update_dimmed (ModestMsgEditWindow *window)
2140 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2141 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2145 gboolean editor_focused;
2147 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2148 editor_focused = gtk_widget_is_focus (priv->msg_body);
2150 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2151 gtk_action_set_sensitive (action, rich_text && editor_focused);
2152 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2153 gtk_action_set_sensitive (action, rich_text && editor_focused);
2154 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2155 gtk_action_set_sensitive (action, rich_text && editor_focused);
2156 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2157 gtk_action_set_sensitive (action, rich_text && editor_focused);
2158 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2159 gtk_action_set_sensitive (action, rich_text && editor_focused);
2160 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2161 gtk_action_set_sensitive (action, rich_text && editor_focused);
2162 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2163 gtk_action_set_sensitive (action, rich_text && editor_focused);
2164 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2165 gtk_action_set_sensitive (action, rich_text && editor_focused);
2166 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2167 gtk_action_set_sensitive (action, rich_text && editor_focused);
2168 widget = priv->font_color_button;
2169 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2170 widget = priv->font_size_toolitem;
2171 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2172 widget = priv->font_face_toolitem;
2173 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2177 setup_insensitive_handlers (ModestMsgEditWindow *window)
2179 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2180 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2183 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2184 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2185 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2186 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2188 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2189 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2190 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2191 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2192 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2193 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2194 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2195 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2196 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2197 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2198 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2199 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2200 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2201 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2202 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2203 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2204 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2205 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2206 widget = priv->font_color_button;
2207 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2208 widget = priv->font_size_toolitem;
2209 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2210 widget = priv->font_face_toolitem;
2211 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2216 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2218 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2221 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2222 gtk_action_set_sensitive (action, can_undo);
2226 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2229 GtkTextIter match_start, match_end;
2231 if (image_id == NULL)
2234 gtk_text_buffer_get_start_iter (buffer, &iter);
2236 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2237 GSList *tags = gtk_text_iter_get_tags (&match_start);
2239 for (node = tags; node != NULL; node = g_slist_next (node)) {
2240 GtkTextTag *tag = (GtkTextTag *) node->data;
2241 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2242 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2243 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2245 offset = gtk_text_iter_get_offset (&match_start);
2246 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2247 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2251 gtk_text_iter_forward_char (&iter);
2256 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2258 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2259 GtkTextIter real_start, real_end;
2260 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2262 if (gtk_text_iter_compare (start, end) > 0) {
2266 real_start = *start;
2270 GSList *tags = gtk_text_iter_get_tags (&real_start);
2272 for (node = tags; node != NULL; node = g_slist_next (node)) {
2273 GtkTextTag *tag = (GtkTextTag *) node->data;
2274 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2275 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2277 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2279 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2282 } while (gtk_text_iter_forward_char (&real_start)&&
2283 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2287 msg_body_focus (GtkWidget *focus,
2288 GdkEventFocus *event,
2292 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2297 recpt_field_changed (GtkTextBuffer *buffer,
2298 ModestMsgEditWindow *editor)
2300 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2301 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2302 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2303 gboolean dim = FALSE;
2306 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2307 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2308 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2310 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2311 gtk_text_buffer_get_char_count (cc_buffer) +
2312 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2314 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2315 gtk_action_set_sensitive (action, !dim);
2316 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2317 gtk_action_set_sensitive (action, !dim);
2321 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2323 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2327 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2329 gboolean rich_text, editor_focused;
2331 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2332 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2333 editor_focused = gtk_widget_is_focus (priv->msg_body);
2336 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2337 else if (!editor_focused)
2338 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2342 reset_modified (ModestMsgEditWindow *editor)
2344 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2345 GtkTextBuffer *buffer;
2347 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2348 gtk_text_buffer_set_modified (buffer, FALSE);
2349 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2350 gtk_text_buffer_set_modified (buffer, FALSE);
2351 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2352 gtk_text_buffer_set_modified (buffer, FALSE);
2353 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2357 is_modified (ModestMsgEditWindow *editor)
2359 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2360 GtkTextBuffer *buffer;
2362 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2363 if (gtk_text_buffer_get_modified (buffer))
2365 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2366 if (gtk_text_buffer_get_modified (buffer))
2368 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2369 if (gtk_text_buffer_get_modified (buffer))
2371 if (gtk_text_buffer_get_modified (priv->text_buffer))
2378 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2380 ModestMsgEditWindowPrivate *priv = NULL;
2382 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2383 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2385 /* check if there's no recipient added */
2386 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2387 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2388 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2389 /* no recipient contents, then select contacts */
2390 modest_msg_edit_window_open_addressbook (window, NULL);
2394 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2396 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2398 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2401 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2408 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2409 ModestMsgEditWindow *window)
2411 modest_msg_edit_window_attach_file (window);
2415 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2417 ModestMsgEditWindow *window)
2419 ModestWindowPrivate *parent_priv;
2424 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2425 selection = gtk_clipboard_wait_for_text (clipboard);
2426 focused = gtk_window_get_focus (GTK_WINDOW (window));
2428 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2429 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2430 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2431 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2435 update_window_title (ModestMsgEditWindow *window)
2437 ModestMsgEditWindowPrivate *priv = NULL;
2438 const gchar *subject;
2440 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2441 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2442 if (subject == NULL || subject[0] == '\0')
2443 subject = _("mail_va_new_email");
2445 gtk_window_set_title (GTK_WINDOW (window), subject);
2450 subject_field_changed (GtkEditable *editable,
2451 ModestMsgEditWindow *window)
2453 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2454 update_window_title (window);
2455 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);