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 to_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 (to_field_changed), obj);
413 to_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
414 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
416 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
417 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
418 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
420 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
422 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
423 frame = gtk_frame_new (NULL);
424 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
426 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
427 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
428 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
430 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL))
431 gtk_widget_hide (priv->cc_field);
432 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL))
433 gtk_widget_hide (priv->bcc_field);
435 gtk_container_add (GTK_CONTAINER(obj), priv->scroll);
436 scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
437 gtk_container_add (GTK_CONTAINER (frame), scroll_area);
438 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
439 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
441 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
442 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
448 modest_msg_edit_window_finalize (GObject *obj)
450 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
453 if (priv->clipboard_change_handler_id > 0) {
454 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
455 priv->clipboard_change_handler_id = 0;
458 /* This had to stay alive for as long as the combobox that used it: */
459 modest_pair_list_free (priv->from_field_protos);
461 G_OBJECT_CLASS(parent_class)->finalize (obj);
465 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
467 GtkWidget *close_dialog;
468 ModestMsgEditWindowPrivate *priv;
471 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
472 modest_window_save_state (MODEST_WINDOW (self));
473 if (is_modified (self)) {
474 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
475 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
476 gtk_widget_destroy (close_dialog);
478 if (response != GTK_RESPONSE_CANCEL) {
479 modest_ui_actions_on_save_to_drafts (NULL, self);
482 /* /\* remove old message from drafts *\/ */
483 /* if (priv->draft_msg) { */
484 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
485 /* TnyAccount *account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(), */
487 /* TNY_ACCOUNT_TYPE_STORE); */
488 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
489 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
490 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
491 /* tny_folder_remove_msg (folder, header, NULL); */
492 /* g_object_unref (folder); */
493 /* g_object_unref (header); */
494 /* g_object_unref (priv->draft_msg); */
495 /* priv->draft_msg = NULL; */
497 gtk_widget_destroy (GTK_WIDGET (self));
503 menubar_to_menu (GtkUIManager *ui_manager)
505 GtkWidget *main_menu;
509 /* Create new main menu */
510 main_menu = gtk_menu_new();
512 /* Get the menubar from the UI manager */
513 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
515 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
519 menu = GTK_WIDGET (iter->data);
520 gtk_widget_reparent(menu, main_menu);
522 iter = g_list_next (iter);
529 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
532 const gchar *to, *cc, *bcc, *subject;
534 ModestMsgEditWindowPrivate *priv;
537 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
538 g_return_if_fail (TNY_IS_MSG (msg));
540 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
542 header = tny_msg_get_header (msg);
543 to = tny_header_get_to (header);
544 cc = tny_header_get_cc (header);
545 bcc = tny_header_get_bcc (header);
546 subject = tny_header_get_subject (header);
549 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
551 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
553 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
555 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
557 update_window_title (self);
559 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
560 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
561 body = modest_tny_msg_get_body (msg, TRUE);
563 if ((body == NULL)||(body[0] == '\0')) {
565 body = modest_text_utils_convert_to_html ("");
567 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
568 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
571 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
574 /* Get the default format required from configuration */
575 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
576 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
579 /* Set the default focus depending on having already a To: field or not */
580 if ((!to)||(*to == '\0')) {
581 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
583 gtk_widget_grab_focus (priv->msg_body);
586 /* TODO: lower priority, select in the From: combo to the
587 value that comes from msg <- not sure, should it be
590 /* Add attachments to the view */
591 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
592 if (priv->attachments == NULL)
593 gtk_widget_hide_all (priv->attachments_caption);
595 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
596 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
598 reset_modified (self);
600 update_dimmed (self);
601 text_buffer_can_undo (priv->text_buffer, FALSE, self);
603 priv->draft_msg = msg;
607 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
610 GList *item_children, *node;
611 GtkWidget *bin_child;
613 bin_child = gtk_bin_get_child (GTK_BIN(item));
615 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
617 for (node = item_children; node != NULL; node = g_list_next (node)) {
618 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
619 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
622 g_list_free (item_children);
626 menu_tool_button_dont_expand (GtkMenuToolButton *item)
629 GList *item_children, *node;
631 box = gtk_bin_get_child (GTK_BIN (item));
632 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
633 item_children = gtk_container_get_children (GTK_CONTAINER (box));
635 for (node = item_children; node != NULL; node = g_list_next (node)) {
636 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
637 if (GTK_IS_TOGGLE_BUTTON (node->data))
638 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
639 else if (GTK_IS_BUTTON (node->data))
640 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
642 g_list_free (item_children);
647 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
649 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
650 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
651 GtkWidget *placeholder;
652 GtkWidget *tool_item;
657 GtkWidget *sizes_menu;
658 GtkWidget *fonts_menu;
659 GSList *radio_group = NULL;
664 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
665 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
667 /* should we hide the toolbar? */
668 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
669 gtk_widget_hide (parent_priv->toolbar);
671 /* Font color placeholder */
672 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
673 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
676 tool_item = GTK_WIDGET (gtk_tool_item_new ());
677 priv->font_color_button = hildon_color_button_new ();
678 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
679 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
680 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
681 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
682 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
683 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
684 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
686 /* Font size and face placeholder */
687 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
688 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
690 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
691 priv->size_tool_button_label = gtk_label_new (NULL);
692 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
693 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
694 size_text,"</span>", NULL);
695 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
697 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
698 sizes_menu = gtk_menu_new ();
699 priv->size_items_group = NULL;
701 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
702 GtkWidget *size_menu_item;
704 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
705 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
706 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
707 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
708 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
709 gtk_widget_show (size_menu_item);
711 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
715 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
716 GtkWidget *item = (GtkWidget *) node->data;
717 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
721 priv->size_items_group = g_slist_reverse (priv->size_items_group);
722 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
723 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
724 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
725 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
726 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
727 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
728 priv->font_size_toolitem = tool_item;
731 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
732 priv->font_tool_button_label = gtk_label_new (NULL);
733 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
734 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
736 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
737 fonts_menu = gtk_menu_new ();
738 priv->font_items_group = NULL;
740 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
741 GtkWidget *font_menu_item;
742 GtkWidget *child_label;
744 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
745 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
746 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
747 wp_get_font_name (font_index), "</span>", NULL);
748 gtk_label_set_markup (GTK_LABEL (child_label), markup);
751 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
752 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
753 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
754 gtk_widget_show (font_menu_item);
756 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
759 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
760 GtkWidget *item = (GtkWidget *) node->data;
761 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
764 priv->font_items_group = g_slist_reverse (priv->font_items_group);
765 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
766 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
767 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
768 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
769 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
770 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
771 priv->font_face_toolitem = tool_item;
773 /* Set expand and homogeneous for remaining items */
774 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
775 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
776 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
777 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
778 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
779 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
780 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
781 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
782 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
790 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
793 ModestWindowPrivate *parent_priv;
794 ModestMsgEditWindowPrivate *priv;
795 GtkActionGroup *action_group;
796 GError *error = NULL;
797 GdkPixbuf *window_icon = NULL;
800 gboolean prefer_formatted;
803 g_return_val_if_fail (msg, NULL);
805 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
807 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
808 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
810 parent_priv->ui_manager = gtk_ui_manager_new();
811 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
812 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
814 /* Add common actions */
815 gtk_action_group_add_actions (action_group,
816 modest_msg_edit_action_entries,
817 G_N_ELEMENTS (modest_msg_edit_action_entries),
819 gtk_action_group_add_toggle_actions (action_group,
820 modest_msg_edit_toggle_action_entries,
821 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
823 gtk_action_group_add_radio_actions (action_group,
824 modest_msg_edit_alignment_radio_action_entries,
825 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
827 G_CALLBACK (modest_ui_actions_on_change_justify),
829 gtk_action_group_add_radio_actions (action_group,
830 modest_msg_edit_zoom_action_entries,
831 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
833 G_CALLBACK (modest_ui_actions_on_change_zoom),
835 gtk_action_group_add_radio_actions (action_group,
836 modest_msg_edit_priority_action_entries,
837 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
839 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
841 gtk_action_group_add_radio_actions (action_group,
842 modest_msg_edit_file_format_action_entries,
843 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
844 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
845 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
847 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
848 g_object_unref (action_group);
850 /* Load the UI definition */
851 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml", &error);
853 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
854 g_clear_error (&error);
857 /* Add accelerators */
858 gtk_window_add_accel_group (GTK_WINDOW (obj),
859 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
862 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
863 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
866 init_window (MODEST_MSG_EDIT_WINDOW(obj));
868 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
870 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
872 g_signal_connect (G_OBJECT(obj), "delete-event",
873 G_CALLBACK(on_delete_event), obj);
875 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
877 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
879 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
881 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
883 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
885 /* Set window icon */
886 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
887 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
889 /* Dim at start clipboard actions */
890 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
891 gtk_action_set_sensitive (action, FALSE);
892 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
893 gtk_action_set_sensitive (action, FALSE);
895 /* Setup the file format */
896 conf = modest_runtime_get_conf ();
897 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
899 g_clear_error (&error);
900 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
902 file_format = (prefer_formatted) ?
903 MODEST_FILE_FORMAT_FORMATTED_TEXT :
904 MODEST_FILE_FORMAT_PLAIN_TEXT;
905 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
907 return (ModestWindow*) obj;
911 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
913 GString **string_buffer = (GString **) user_data;
915 *string_buffer = g_string_append (*string_buffer, buffer);
921 * @result: A new string which should be freed with g_free().
924 get_formatted_data (ModestMsgEditWindow *edit_window)
926 ModestMsgEditWindowPrivate *priv;
927 GString *string_buffer = g_string_new ("");
929 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
931 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
933 return g_string_free (string_buffer, FALSE);
938 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
941 const gchar *account_name;
942 ModestMsgEditWindowPrivate *priv;
944 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
946 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
948 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
949 g_return_val_if_fail (account_name, NULL);
952 /* don't free these (except from) */
953 data = g_slice_new0 (MsgData);
954 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
956 data->account_name = g_strdup (account_name);
957 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
958 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
959 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
960 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
961 if (priv->draft_msg) {
962 data->draft_msg = g_object_ref (priv->draft_msg);
964 data->draft_msg = NULL;
967 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
969 gtk_text_buffer_get_bounds (buf, &b, &e);
970 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
972 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
973 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
975 data->html_body = NULL;
977 data->attachments = priv->attachments; /* TODO: copy and free ? */
978 data->priority_flags = priv->priority_flags;
983 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
985 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
988 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
996 g_free (data->subject);
997 g_free (data->plain_body);
998 g_free (data->html_body);
999 if (data->draft_msg != NULL) {
1000 g_object_unref (data->draft_msg);
1001 data->draft_msg = NULL;
1003 g_free (data->account_name);
1005 /* TODO: Free data->attachments? */
1007 g_slice_free (MsgData, data);
1011 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1014 ModestMsgEditWindowPrivate *priv = NULL;
1015 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1017 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1019 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1021 return MODEST_MSG_EDIT_FORMAT_HTML;
1023 return MODEST_MSG_EDIT_FORMAT_TEXT;
1027 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1028 ModestMsgEditFormat format)
1030 ModestMsgEditWindowPrivate *priv;
1032 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1033 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1036 case MODEST_MSG_EDIT_FORMAT_HTML:
1037 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1039 case MODEST_MSG_EDIT_FORMAT_TEXT:
1040 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1043 g_return_if_reached ();
1047 ModestMsgEditFormatState *
1048 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1050 ModestMsgEditFormatState *format_state = NULL;
1051 ModestMsgEditWindowPrivate *priv;
1052 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1054 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1055 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1057 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1059 format_state = g_new0 (ModestMsgEditFormatState, 1);
1060 format_state->bold = buffer_format->bold&0x1;
1061 format_state->italics = buffer_format->italic&0x1;
1062 format_state->bullet = buffer_format->bullet&0x1;
1063 format_state->color = buffer_format->color;
1064 format_state->font_size = buffer_format->font_size;
1065 format_state->font_family = wp_get_font_name (buffer_format->font);
1066 format_state->justification = buffer_format->justification;
1067 g_free (buffer_format);
1069 return format_state;
1074 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1075 const ModestMsgEditFormatState *format_state)
1077 ModestMsgEditWindowPrivate *priv;
1078 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1079 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1080 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1081 g_return_if_fail (format_state != NULL);
1083 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1084 gtk_widget_grab_focus (priv->msg_body);
1085 buffer_format->bold = (format_state->bold != FALSE);
1086 buffer_format->italic = (format_state->italics != FALSE);
1087 buffer_format->color = format_state->color;
1088 buffer_format->font_size = format_state->font_size;
1089 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1090 buffer_format->justification = format_state->justification;
1091 buffer_format->bullet = format_state->bullet;
1093 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1095 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1096 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1097 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1098 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1099 buffer_format->cs.font = (buffer_format->font != current_format->font);
1100 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1101 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1103 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1104 if (buffer_format->cs.bold) {
1105 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1107 if (buffer_format->cs.italic) {
1108 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1110 if (buffer_format->cs.color) {
1111 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1113 if (buffer_format->cs.font_size) {
1114 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1116 if (buffer_format->cs.justification) {
1117 switch (buffer_format->justification) {
1118 case GTK_JUSTIFY_LEFT:
1119 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1121 case GTK_JUSTIFY_CENTER:
1122 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1124 case GTK_JUSTIFY_RIGHT:
1125 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1132 if (buffer_format->cs.font) {
1133 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1135 if (buffer_format->cs.bullet) {
1136 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
1138 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1139 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1141 g_free (current_format);
1146 toggle_action_set_active_block_notify (GtkToggleAction *action,
1149 GSList *proxies = NULL;
1151 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1152 proxies != NULL; proxies = g_slist_next (proxies)) {
1153 GtkWidget *widget = (GtkWidget *) proxies->data;
1154 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1157 gtk_toggle_action_set_active (action, value);
1159 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1160 proxies != NULL; proxies = g_slist_next (proxies)) {
1161 GtkWidget *widget = (GtkWidget *) proxies->data;
1162 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1167 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1169 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1171 ModestWindowPrivate *parent_priv;
1172 ModestMsgEditWindowPrivate *priv;
1173 GtkWidget *new_size_menuitem;
1174 GtkWidget *new_font_menuitem;
1176 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1177 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1179 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1180 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1181 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1182 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1184 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1185 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1186 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1189 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1191 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1192 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1194 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1195 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1197 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1198 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1200 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1201 G_CALLBACK (modest_msg_edit_window_color_button_change),
1203 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1204 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1205 G_CALLBACK (modest_msg_edit_window_color_button_change),
1208 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1209 buffer_format->font_size))->data);
1210 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1214 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1215 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1216 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1218 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1219 G_CALLBACK (modest_msg_edit_window_size_change),
1221 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1222 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1223 G_CALLBACK (modest_msg_edit_window_size_change),
1227 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1228 buffer_format->font))->data);
1229 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1233 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1234 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1235 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1237 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1238 G_CALLBACK (modest_msg_edit_window_font_change),
1240 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1241 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1242 G_CALLBACK (modest_msg_edit_window_font_change),
1246 g_free (buffer_format);
1252 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1255 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1256 ModestMsgEditWindowPrivate *priv;
1257 GtkWidget *dialog = NULL;
1259 const GdkColor *new_color = NULL;
1261 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1262 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1264 #ifdef MODEST_HILDON_VERSION_0
1265 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1266 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1268 dialog = hildon_color_chooser_new ();
1269 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1270 #endif /*MODEST_HILDON_VERSION_0*/
1271 g_free (buffer_format);
1273 response = gtk_dialog_run (GTK_DIALOG (dialog));
1275 case GTK_RESPONSE_OK: {
1276 #ifdef MODEST_HILDON_VERSION_0
1277 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1280 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1282 #endif /*MODEST_HILDON_VERSION_0*/
1289 gtk_widget_destroy (dialog);
1291 if (new_color != NULL)
1292 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1297 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1300 ModestMsgEditWindowPrivate *priv;
1301 GtkWidget *dialog = NULL;
1303 GdkColor *old_color = NULL;
1304 const GdkColor *new_color = NULL;
1306 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1307 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1309 #ifdef MODEST_HILDON_VERSION_0
1310 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1311 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1313 dialog = hildon_color_chooser_new ();
1314 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1315 #endif /*MODEST_HILDON_VERSION_9*/
1317 response = gtk_dialog_run (GTK_DIALOG (dialog));
1319 case GTK_RESPONSE_OK: {
1320 #ifdef MODEST_HILDON_VERSION_0
1321 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1324 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1326 #endif /*MODEST_HILDON_VERSION_0*/
1332 gtk_widget_destroy (dialog);
1334 if (new_color != NULL)
1335 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1340 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1343 ModestMsgEditWindowPrivate *priv;
1344 GtkWidget *dialog = NULL;
1346 gchar *filename = NULL;
1348 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1350 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1352 response = gtk_dialog_run (GTK_DIALOG (dialog));
1354 case GTK_RESPONSE_OK:
1355 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1360 gtk_widget_destroy (dialog);
1363 GdkPixbuf *pixbuf = NULL;
1364 GtkTextIter position;
1365 GtkTextMark *insert_mark;
1367 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1370 GdkPixbufFormat *pixbuf_format;
1372 image_file_id = g_open (filename, O_RDONLY, 0);
1373 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1374 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1375 TnyMimePart *image_part;
1376 TnyStream *image_stream;
1382 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1383 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1384 mime_type = mime_types[0];
1386 mime_type = "image/unknown";
1388 image_part = tny_platform_factory_new_mime_part
1389 (modest_runtime_get_platform_factory ());
1390 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1392 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1393 g_strfreev (mime_types);
1395 content_id = g_strdup_printf ("%d", priv->last_cid);
1396 tny_mime_part_set_content_id (image_part, content_id);
1397 g_free (content_id);
1400 basename = g_path_get_basename (filename);
1401 tny_mime_part_set_filename (image_part, basename);
1404 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1405 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1406 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1407 priv->attachments = g_list_prepend (priv->attachments, image_part);
1408 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1410 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1411 gtk_widget_show_all (priv->attachments_caption);
1412 } else if (image_file_id == -1) {
1413 close (image_file_id);
1422 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1425 ModestMsgEditWindowPrivate *priv;
1426 GtkWidget *dialog = NULL;
1428 gchar *uri = NULL, *filename = NULL;
1430 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1432 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1434 response = gtk_dialog_run (GTK_DIALOG (dialog));
1436 case GTK_RESPONSE_OK:
1437 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
1438 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1443 gtk_widget_destroy (dialog);
1447 GnomeVFSHandle *handle = NULL;
1448 GnomeVFSResult result;
1450 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1451 if (result == GNOME_VFS_OK) {
1452 TnyMimePart *mime_part;
1454 const gchar *mime_type = NULL;
1457 GnomeVFSFileInfo info;
1459 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1460 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1461 mime_part = tny_platform_factory_new_mime_part
1462 (modest_runtime_get_platform_factory ());
1463 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1465 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1467 content_id = g_strdup_printf ("%d", priv->last_cid);
1468 tny_mime_part_set_content_id (mime_part, content_id);
1469 g_free (content_id);
1472 basename = g_path_get_basename (filename);
1473 tny_mime_part_set_filename (mime_part, basename);
1476 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1477 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1479 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1480 gtk_widget_show_all (priv->attachments_caption);
1487 modest_msg_edit_window_attach_file_noninteractive (
1488 ModestMsgEditWindow *window,
1492 ModestMsgEditWindowPrivate *priv;
1494 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1499 file_id = g_open (filename, O_RDONLY, 0);
1500 if (file_id != -1) {
1501 TnyMimePart *mime_part;
1503 const gchar *mime_type;
1507 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1508 mime_part = tny_platform_factory_new_mime_part
1509 (modest_runtime_get_platform_factory ());
1510 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1512 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1514 content_id = g_strdup_printf ("%d", priv->last_cid);
1515 tny_mime_part_set_content_id (mime_part, content_id);
1516 g_free (content_id);
1519 basename = g_path_get_basename (filename);
1520 tny_mime_part_set_filename (mime_part, basename);
1523 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1524 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1526 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1527 gtk_widget_show_all (priv->attachments_caption);
1528 } else if (file_id == -1) {
1535 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1538 ModestMsgEditWindowPrivate *priv;
1539 gboolean clean_list = FALSE;
1541 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1542 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1544 if (att_list == NULL) {
1545 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1549 if (att_list == NULL) {
1550 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1552 GtkWidget *confirmation_dialog = NULL;
1553 gboolean dialog_response;
1555 if (att_list->next == NULL) {
1556 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1557 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1558 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1561 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1563 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1564 gtk_widget_destroy (confirmation_dialog);
1565 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1567 for (node = att_list; node != NULL; node = g_list_next (node)) {
1568 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1569 const gchar *att_id;
1570 priv->attachments = g_list_remove (priv->attachments, mime_part);
1572 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1574 att_id = tny_mime_part_get_content_id (mime_part);
1576 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1578 g_object_unref (mime_part);
1583 g_list_free (att_list);
1587 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1590 ModestMsgEditWindowPrivate *priv;
1591 GdkColor *new_color;
1592 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1594 #ifdef MODEST_HILDON_VERSION_0
1595 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1598 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1600 #endif /*MODEST_HILDON_VERSION_0*/
1602 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1604 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1609 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1612 ModestMsgEditWindowPrivate *priv;
1613 gint new_size_index;
1614 ModestMsgEditWindow *window;
1617 window = MODEST_MSG_EDIT_WINDOW (userdata);
1618 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1619 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1621 if (gtk_check_menu_item_get_active (menu_item)) {
1623 WPTextBufferFormat format;
1625 memset (&format, 0, sizeof (format));
1626 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1628 label = gtk_bin_get_child (GTK_BIN (menu_item));
1630 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1631 format.cs.font_size = TRUE;
1632 format.cs.text_position = TRUE;
1633 format.cs.font = TRUE;
1634 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1635 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1637 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1638 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1639 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1641 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1642 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1643 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1649 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1652 ModestMsgEditWindowPrivate *priv;
1653 gint new_font_index;
1654 ModestMsgEditWindow *window;
1657 window = MODEST_MSG_EDIT_WINDOW (userdata);
1658 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1659 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1661 if (gtk_check_menu_item_get_active (menu_item)) {
1664 label = gtk_bin_get_child (GTK_BIN (menu_item));
1666 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1668 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1669 (gpointer) new_font_index))
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='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1674 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1680 modest_msg_edit_window_set_zoom (ModestWindow *window,
1683 ModestMsgEditWindowPrivate *priv;
1685 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1687 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1688 priv->zoom_level = zoom;
1689 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1693 modest_msg_edit_window_get_zoom (ModestWindow *window)
1695 ModestMsgEditWindowPrivate *priv;
1697 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1699 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1700 return priv->zoom_level;
1704 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1706 ModestWindowPrivate *parent_priv;
1707 GtkRadioAction *zoom_radio_action;
1708 GSList *group, *node;
1710 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1711 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1712 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1714 group = gtk_radio_action_get_group (zoom_radio_action);
1716 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1717 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1721 for (node = group; node != NULL; node = g_slist_next (node)) {
1722 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1723 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1731 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1733 ModestWindowPrivate *parent_priv;
1734 GtkRadioAction *zoom_radio_action;
1735 GSList *group, *node;
1737 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1738 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1739 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1741 group = gtk_radio_action_get_group (zoom_radio_action);
1743 for (node = group; node != NULL; node = g_slist_next (node)) {
1744 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1745 if (node->next != NULL) {
1746 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1749 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1757 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1759 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1760 ModestWindowPrivate *parent_priv;
1761 ModestWindowMgr *mgr;
1762 gboolean is_fullscreen;
1763 GtkAction *fs_toggle_action;
1766 mgr = modest_runtime_get_window_mgr ();
1767 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1769 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1771 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1772 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1773 if (is_fullscreen != active)
1774 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1782 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1784 ModestWindowPrivate *parent_priv;
1785 GtkAction *fs_toggle_action;
1788 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1790 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1791 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1792 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1796 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1799 ModestMsgEditWindowPrivate *priv = NULL;
1800 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1802 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1804 gtk_widget_show (priv->cc_caption);
1806 gtk_widget_hide (priv->cc_caption);
1810 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1813 ModestMsgEditWindowPrivate *priv = NULL;
1814 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1816 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1818 gtk_widget_show (priv->bcc_caption);
1820 gtk_widget_hide (priv->bcc_caption);
1824 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1825 ModestRecptEditor *editor)
1827 ModestMsgEditWindowPrivate *priv;
1829 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1830 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1831 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1833 if (editor == NULL) {
1834 GtkWidget *view_focus;
1835 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1837 /* This code should be kept in sync with ModestRecptEditor. The
1838 textview inside the recpt editor is the one that really gets the
1839 focus. As it's inside a scrolled window, and this one inside the
1840 hbox recpt editor inherits from, we'll need to go up in the
1841 hierarchy to know if the text view is part of the recpt editor
1842 or if it's a different text entry */
1844 if (gtk_widget_get_parent (view_focus)) {
1845 GtkWidget *first_parent;
1847 first_parent = gtk_widget_get_parent (view_focus);
1848 if (gtk_widget_get_parent (first_parent) &&
1849 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1850 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1855 editor = MODEST_RECPT_EDITOR (priv->to_field);
1859 modest_address_book_select_addresses (editor);
1864 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1866 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1868 modest_msg_edit_window_open_addressbook (window, NULL);
1872 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1873 gboolean show_toolbar)
1875 ModestWindowPrivate *parent_priv;
1877 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1878 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1880 /* FIXME: we can not just use the code of
1881 modest_msg_edit_window_setup_toolbar because it has a
1882 mixture of both initialization and creation code. */
1885 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1887 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1891 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1892 TnyHeaderFlags priority_flags)
1894 ModestMsgEditWindowPrivate *priv;
1896 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1898 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1899 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1901 if (priv->priority_flags != priority_flags) {
1903 priv->priority_flags = priority_flags;
1905 switch (priority_flags) {
1906 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1907 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1908 gtk_widget_show (priv->priority_icon);
1910 case TNY_HEADER_FLAG_LOW_PRIORITY:
1911 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1912 gtk_widget_show (priv->priority_icon);
1915 gtk_widget_hide (priv->priority_icon);
1922 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1925 ModestMsgEditWindowPrivate *priv;
1926 gint current_format;
1928 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1930 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1932 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1933 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1935 if (current_format != file_format) {
1936 switch (file_format) {
1937 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1938 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1940 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1944 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1945 response = gtk_dialog_run (GTK_DIALOG (dialog));
1946 gtk_widget_destroy (dialog);
1947 if (response == GTK_RESPONSE_OK)
1948 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1952 update_dimmed (window);
1957 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1960 ModestMsgEditWindowPrivate *priv;
1961 WPTextBufferFormat oldfmt, fmt;
1962 gint old_position = 0;
1966 GdkColor *color = NULL;
1967 gboolean bold, bold_set, italic, italic_set;
1968 gboolean underline, underline_set;
1969 gboolean strikethrough, strikethrough_set;
1970 gboolean position_set;
1971 gboolean font_size_set, font_set, color_set;
1974 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1975 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1977 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
1979 /* First we get the currently selected font information */
1980 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
1981 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
1983 switch (oldfmt.text_position) {
1984 case TEXT_POSITION_NORMAL:
1987 case TEXT_POSITION_SUPERSCRIPT:
1995 g_object_set (G_OBJECT (dialog),
1996 "bold", oldfmt.bold != FALSE,
1997 "bold-set", !oldfmt.cs.bold,
1998 "underline", oldfmt.underline != FALSE,
1999 "underline-set", !oldfmt.cs.underline,
2000 "italic", oldfmt.italic != FALSE,
2001 "italic-set", !oldfmt.cs.italic,
2002 "strikethrough", oldfmt.strikethrough != FALSE,
2003 "strikethrough-set", !oldfmt.cs.strikethrough,
2004 "color", &oldfmt.color,
2005 "color-set", !oldfmt.cs.color,
2006 "size", wp_font_size[oldfmt.font_size],
2007 "size-set", !oldfmt.cs.font_size,
2008 "position", old_position,
2009 "position-set", !oldfmt.cs.text_position,
2010 "family", wp_get_font_name (oldfmt.font),
2011 "family-set", !oldfmt.cs.font,
2014 gtk_widget_show_all (dialog);
2015 response = gtk_dialog_run (GTK_DIALOG (dialog));
2016 if (response == GTK_RESPONSE_OK) {
2018 g_object_get( dialog,
2020 "bold-set", &bold_set,
2021 "underline", &underline,
2022 "underline-set", &underline_set,
2024 "italic-set", &italic_set,
2025 "strikethrough", &strikethrough,
2026 "strikethrough-set", &strikethrough_set,
2028 "color-set", &color_set,
2030 "size-set", &font_size_set,
2031 "family", &font_name,
2032 "family-set", &font_set,
2033 "position", &position,
2034 "position-set", &position_set,
2039 if (response == GTK_RESPONSE_OK) {
2040 memset(&fmt, 0, sizeof(fmt));
2046 fmt.italic = italic;
2047 fmt.cs.italic = TRUE;
2049 if (underline_set) {
2050 fmt.underline = underline;
2051 fmt.cs.underline = TRUE;
2053 if (strikethrough_set) {
2054 fmt.strikethrough = strikethrough;
2055 fmt.cs.strikethrough = TRUE;
2060 ? TEXT_POSITION_NORMAL
2061 : ( ( position == 1 )
2062 ? TEXT_POSITION_SUPERSCRIPT
2063 : TEXT_POSITION_SUBSCRIPT );
2064 fmt.cs.text_position = TRUE;
2068 fmt.cs.color = TRUE;
2071 fmt.font = wp_get_font_index(font_name,
2076 if (font_size_set) {
2077 fmt.font_size = wp_get_font_size_index(
2078 font_size, DEFAULT_FONT_SIZE);
2079 fmt.cs.font_size = TRUE;
2081 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2083 gtk_widget_destroy (dialog);
2085 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2089 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2091 ModestMsgEditWindowPrivate *priv;
2093 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2094 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2096 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2098 update_dimmed (window);
2103 update_dimmed (ModestMsgEditWindow *window)
2105 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2106 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2110 gboolean editor_focused;
2112 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2113 editor_focused = gtk_widget_is_focus (priv->msg_body);
2115 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2116 gtk_action_set_sensitive (action, rich_text && editor_focused);
2117 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2118 gtk_action_set_sensitive (action, rich_text && editor_focused);
2119 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2120 gtk_action_set_sensitive (action, rich_text && editor_focused);
2121 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2122 gtk_action_set_sensitive (action, rich_text && editor_focused);
2123 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2124 gtk_action_set_sensitive (action, rich_text && editor_focused);
2125 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2126 gtk_action_set_sensitive (action, rich_text && editor_focused);
2127 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2128 gtk_action_set_sensitive (action, rich_text && editor_focused);
2129 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2130 gtk_action_set_sensitive (action, rich_text && editor_focused);
2131 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2132 gtk_action_set_sensitive (action, rich_text && editor_focused);
2133 widget = priv->font_color_button;
2134 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2135 widget = priv->font_size_toolitem;
2136 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2137 widget = priv->font_face_toolitem;
2138 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2142 setup_insensitive_handlers (ModestMsgEditWindow *window)
2144 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2145 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2148 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2149 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2150 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2151 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2153 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2154 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2155 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2156 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2157 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2158 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2159 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2160 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2161 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2162 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2163 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2164 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2165 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2166 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2167 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2168 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2169 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2170 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2171 widget = priv->font_color_button;
2172 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2173 widget = priv->font_size_toolitem;
2174 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2175 widget = priv->font_face_toolitem;
2176 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2181 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2183 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2186 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2187 gtk_action_set_sensitive (action, can_undo);
2191 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2194 GtkTextIter match_start, match_end;
2196 if (image_id == NULL)
2199 gtk_text_buffer_get_start_iter (buffer, &iter);
2201 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2202 GSList *tags = gtk_text_iter_get_tags (&match_start);
2204 for (node = tags; node != NULL; node = g_slist_next (node)) {
2205 GtkTextTag *tag = (GtkTextTag *) node->data;
2206 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2207 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2208 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2210 offset = gtk_text_iter_get_offset (&match_start);
2211 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2212 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2216 gtk_text_iter_forward_char (&iter);
2221 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2223 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2224 GtkTextIter real_start, real_end;
2225 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2227 if (gtk_text_iter_compare (start, end) > 0) {
2231 real_start = *start;
2235 GSList *tags = gtk_text_iter_get_tags (&real_start);
2237 for (node = tags; node != NULL; node = g_slist_next (node)) {
2238 GtkTextTag *tag = (GtkTextTag *) node->data;
2239 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2240 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2242 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2244 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2247 } while (gtk_text_iter_forward_char (&real_start)&&
2248 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2252 msg_body_focus (GtkWidget *focus,
2253 GdkEventFocus *event,
2257 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2262 to_field_changed (GtkTextBuffer *buffer,
2263 ModestMsgEditWindow *editor)
2265 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2268 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2269 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2270 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2271 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2275 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2277 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2281 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2283 gboolean rich_text, editor_focused;
2285 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2286 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2287 editor_focused = gtk_widget_is_focus (priv->msg_body);
2290 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2291 else if (!editor_focused)
2292 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2296 reset_modified (ModestMsgEditWindow *editor)
2298 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2299 GtkTextBuffer *buffer;
2301 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2302 gtk_text_buffer_set_modified (buffer, FALSE);
2303 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2304 gtk_text_buffer_set_modified (buffer, FALSE);
2305 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2306 gtk_text_buffer_set_modified (buffer, FALSE);
2307 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2311 is_modified (ModestMsgEditWindow *editor)
2313 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2314 GtkTextBuffer *buffer;
2316 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2317 if (gtk_text_buffer_get_modified (buffer))
2319 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2320 if (gtk_text_buffer_get_modified (buffer))
2322 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2323 if (gtk_text_buffer_get_modified (buffer))
2325 if (gtk_text_buffer_get_modified (priv->text_buffer))
2332 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2334 ModestMsgEditWindowPrivate *priv = NULL;
2336 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2337 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2339 /* check if there's no recipient added */
2340 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2341 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2342 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2343 /* no recipient contents, then select contacts */
2344 modest_msg_edit_window_open_addressbook (window, NULL);
2348 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2350 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2352 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2355 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2362 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2363 ModestMsgEditWindow *window)
2365 modest_msg_edit_window_attach_file (window);
2369 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2371 ModestMsgEditWindow *window)
2373 ModestWindowPrivate *parent_priv;
2378 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2379 selection = gtk_clipboard_wait_for_text (clipboard);
2380 focused = gtk_window_get_focus (GTK_WINDOW (window));
2382 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2383 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2384 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2385 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2389 update_window_title (ModestMsgEditWindow *window)
2391 ModestMsgEditWindowPrivate *priv = NULL;
2392 const gchar *subject;
2394 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2395 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2396 if (subject == NULL || subject[0] == '\0')
2397 subject = _("mail_va_new_email");
2399 gtk_window_set_title (GTK_WINDOW (window), subject);
2404 subject_field_changed (GtkEditable *editable,
2405 ModestMsgEditWindow *window)
2407 update_window_title (window);