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>
38 #include <tny-camel-mem-stream.h>
42 #include <modest-account-mgr.h>
43 #include <modest-account-mgr-helpers.h>
45 #include <widgets/modest-msg-edit-window.h>
46 #include <modest-selector-picker.h>
47 #include <widgets/modest-recpt-editor.h>
48 #include <widgets/modest-attachments-view.h>
50 #include <modest-runtime.h>
52 #include "modest-platform.h"
53 #include "modest-icon-names.h"
54 #include "modest-widget-memory.h"
55 #include "modest-window-priv.h"
56 #include "modest-mail-operation.h"
57 #include "modest-tny-platform-factory.h"
58 #include "modest-tny-msg.h"
59 #include "modest-tny-folder.h"
60 #include "modest-tny-account.h"
61 #include "modest-address-book.h"
62 #include "modest-text-utils.h"
63 #include <tny-simple-list.h>
64 #include <wptextview.h>
65 #include <wptextbuffer.h>
66 #include <hildon/hildon-pannable-area.h>
67 #include "modest-msg-edit-window-ui-dimming.h"
69 #include "modest-hildon-includes.h"
70 #ifdef MODEST_HAVE_HILDON0_WIDGETS
71 #include <hildon-widgets/hildon-color-chooser.h>
73 #include "widgets/modest-msg-edit-window-ui.h"
74 #ifdef MODEST_HAVE_HILDON0_WIDGETS
75 #include <libgnomevfs/gnome-vfs-mime-utils.h>
77 #include <libgnomevfs/gnome-vfs-mime.h>
79 #include <modest-utils.h>
80 #include "modest-maemo-utils.h"
81 #include <modest-ui-constants.h>
84 #define DEFAULT_FONT_SIZE 3
85 #define DEFAULT_FONT 2
86 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
87 #define DEFAULT_MAIN_VBOX_SPACING 6
88 #define SUBJECT_MAX_LENGTH 1000
89 #define IMAGE_MAX_WIDTH 560
90 #define DEFAULT_FONT_SCALE 1.5
92 static gboolean is_wp_text_buffer_started = FALSE;
94 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
95 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
96 static void modest_msg_edit_window_finalize (GObject *obj);
98 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
99 static void body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
100 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
102 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
103 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
104 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
105 static void text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
106 GtkTextIter *start, GtkTextIter *end,
108 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
109 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
110 static void subject_field_insert_text (GtkEditable *editable,
112 gint new_text_length,
114 ModestMsgEditWindow *window);
115 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
117 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
119 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
121 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
123 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
124 ModestRecptEditor *editor);
125 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
126 ModestMsgEditWindow *window);
128 /* ModestWindow methods implementation */
129 static void modest_msg_edit_window_disconnect_signals (ModestWindow *window);
130 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
131 gboolean show_toolbar);
132 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
134 ModestMsgEditWindow *window);
135 static void modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window);
136 static void subject_field_move_cursor (GtkEntry *entry,
137 GtkMovementStep step,
141 static void update_window_title (ModestMsgEditWindow *window);
144 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
145 ModestMsgEditWindow *window);
146 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
147 ModestMsgEditWindow *window);
148 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
150 GtkTextIter *match_start,
151 GtkTextIter *match_end);
153 static void remove_tags (WPTextBuffer *buffer);
155 static void on_account_removed (TnyAccountStore *account_store,
159 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
160 static void set_zoom_do_nothing (ModestWindow *window, gdouble zoom);
161 static gdouble get_zoom_do_nothing (ModestWindow *window);
163 static void init_window (ModestMsgEditWindow *obj);
165 gboolean scroll_drag_timeout (gpointer userdata);
166 static void correct_scroll (ModestMsgEditWindow *w);
167 static void correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused);
168 static void text_buffer_end_user_action (GtkTextBuffer *buffer,
169 ModestMsgEditWindow *userdata);
170 static void text_buffer_mark_set (GtkTextBuffer *buffer,
173 ModestMsgEditWindow *userdata);
175 static void DEBUG_BUFFER (WPTextBuffer *buffer)
179 g_message ("BEGIN BUFFER OF SIZE %d", gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (buffer)));
181 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
182 while (!gtk_text_iter_is_end (&iter)) {
183 GString *output = g_string_new ("");
184 GSList *toggled_tags;
187 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
188 g_string_append_printf (output, "%d: CLOSED [ ", gtk_text_iter_get_offset (&iter));
189 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
190 GtkTextTag *tag = (GtkTextTag *) node->data;
192 g_object_get (G_OBJECT (tag), "name", &name, NULL);
193 output = g_string_append (output, name);
194 g_string_append (output, " ");
196 output = g_string_append (output, "] OPENED [ ");
197 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
198 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
199 GtkTextTag *tag = (GtkTextTag *) node->data;
201 g_object_get (G_OBJECT (tag), "name", &name, NULL);
202 output = g_string_append (output, name);
203 g_string_append (output, " ");
205 output = g_string_append (output, "]\n");
206 g_message ("%s", output->str);
207 g_string_free (output, TRUE);
208 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
210 g_message ("END BUFFER");
215 /* static gboolean */
216 /* on_key_pressed (GtkWidget *self, */
217 /* GdkEventKey *event, */
218 /* gpointer user_data); */
220 /* list my signals */
227 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
228 struct _ModestMsgEditWindowPrivate {
231 GtkWidget *header_box;
233 ModestPairList *from_field_protos;
234 GtkWidget *from_field;
235 gchar *original_account_name;
239 GtkWidget *bcc_field;
240 GtkWidget *subject_field;
241 GtkWidget *attachments_view;
242 GtkWidget *priority_icon;
243 GtkWidget *add_attachment_button;
245 GtkWidget *cc_caption;
246 GtkWidget *bcc_caption;
247 gboolean update_caption_visibility;
248 GtkWidget *attachments_caption;
250 GtkTextBuffer *text_buffer;
252 GtkWidget *font_size_toolitem;
253 GtkWidget *font_face_toolitem;
254 GtkWidget *font_color_button;
255 GtkWidget *font_color_toolitem;
256 GSList *font_items_group;
257 GtkWidget *font_tool_button_label;
258 GSList *size_items_group;
259 GtkWidget *size_tool_button_label;
261 GtkWidget *find_toolbar;
264 GtkWidget *font_dialog;
267 guint scroll_drag_timeout_id;
271 TnyList *attachments;
276 TnyHeaderFlags priority_flags;
278 gboolean can_undo, can_redo;
279 gulong clipboard_change_handler_id;
280 gulong default_clipboard_change_handler_id;
281 gulong account_removed_handler_id;
282 guint clipboard_owner_idle;
283 gchar *clipboard_text;
292 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
293 MODEST_TYPE_MSG_EDIT_WINDOW, \
294 ModestMsgEditWindowPrivate))
296 static GtkWindowClass *parent_class = NULL;
298 /* uncomment the following if you have defined any signals */
299 /* static guint signals[LAST_SIGNAL] = {0}; */
302 modest_msg_edit_window_get_type (void)
304 static GType my_type = 0;
306 static const GTypeInfo my_info = {
307 sizeof(ModestMsgEditWindowClass),
308 NULL, /* base init */
309 NULL, /* base finalize */
310 (GClassInitFunc) modest_msg_edit_window_class_init,
311 NULL, /* class finalize */
312 NULL, /* class data */
313 sizeof(ModestMsgEditWindow),
315 (GInstanceInitFunc) modest_msg_edit_window_init,
318 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
319 "ModestMsgEditWindow",
327 save_state (ModestWindow *self)
329 modest_widget_memory_save (modest_runtime_get_conf(),
330 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
335 restore_settings (ModestMsgEditWindow *self)
337 ModestConf *conf = NULL;
339 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
341 conf = modest_runtime_get_conf ();
343 /* Dim at start clipboard actions */
344 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
345 gtk_action_set_sensitive (action, FALSE);
346 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
347 gtk_action_set_sensitive (action, FALSE);
348 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
349 gtk_action_set_sensitive (action, FALSE);
351 modest_widget_memory_restore (conf, G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
356 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
358 GObjectClass *gobject_class;
359 ModestWindowClass *modest_window_class;
360 gobject_class = (GObjectClass*) klass;
361 modest_window_class = (ModestWindowClass*) klass;
363 parent_class = g_type_class_peek_parent (klass);
364 gobject_class->finalize = modest_msg_edit_window_finalize;
366 modest_window_class->set_zoom_func = set_zoom_do_nothing;
367 modest_window_class->get_zoom_func = get_zoom_do_nothing;
368 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
369 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
370 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
371 modest_window_class->save_state_func = save_state;
372 modest_window_class->disconnect_signals_func = modest_msg_edit_window_disconnect_signals;
374 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
378 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
380 ModestMsgEditWindowPrivate *priv;
381 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
383 priv->msg_body = NULL;
385 priv->from_field = NULL;
386 priv->to_field = NULL;
387 priv->cc_field = NULL;
388 priv->bcc_field = NULL;
389 priv->subject_field = NULL;
390 priv->attachments = TNY_LIST (tny_simple_list_new ());
391 priv->images = TNY_LIST (tny_simple_list_new ());
392 priv->images_size = 0;
393 priv->images_count = 0;
396 priv->cc_caption = NULL;
397 priv->bcc_caption = NULL;
398 priv->update_caption_visibility = FALSE;
400 priv->priority_flags = 0;
402 priv->find_toolbar = NULL;
403 priv->last_search = NULL;
405 priv->draft_msg = NULL;
406 priv->outbox_msg = NULL;
407 priv->msg_uid = NULL;
409 priv->can_undo = FALSE;
410 priv->can_redo = FALSE;
411 priv->clipboard_change_handler_id = 0;
412 priv->default_clipboard_change_handler_id = 0;
413 priv->account_removed_handler_id = 0;
414 priv->clipboard_owner_idle = 0;
415 priv->clipboard_text = NULL;
418 priv->scroll_drag_timeout_id = 0;
419 priv->last_upper = 0.0;
421 priv->font_dialog = NULL;
423 if (!is_wp_text_buffer_started) {
424 is_wp_text_buffer_started = TRUE;
425 wp_text_buffer_library_init ();
430 hildon_program_add_window (hildon_program_get_instance(),
436 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
438 static ModestPairList*
439 get_transports (void)
441 GSList *transports = NULL;
443 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
444 GSList *accounts = modest_account_mgr_account_names (account_mgr,
445 TRUE /* only enabled accounts. */);
447 GSList *cursor = accounts;
449 gchar *account_name = cursor->data;
450 gchar *from_string = NULL;
452 from_string = modest_account_mgr_get_from_string (account_mgr,
456 if (from_string && account_name) {
457 gchar *name = account_name;
458 ModestPair *pair = modest_pair_new ((gpointer) name,
459 (gpointer) from_string , TRUE);
460 transports = g_slist_prepend (transports, pair);
463 cursor = cursor->next;
465 g_slist_free (accounts); /* only free the accounts, not the elements,
466 * because they are used in the pairlist */
470 static void window_focus (GtkWindow *window,
474 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
478 scroll_drag_timeout (gpointer userdata)
480 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
481 ModestMsgEditWindowPrivate *priv;
483 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
485 correct_scroll_without_drag_check (win, TRUE);
487 priv->scroll_drag_timeout_id = 0;
493 correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused)
495 ModestMsgEditWindowPrivate *priv;
498 GdkRectangle rectangle;
502 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
504 if (only_if_focused && !gtk_widget_is_focus (priv->msg_body))
507 insert = gtk_text_buffer_get_insert (priv->text_buffer);
508 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
510 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
511 offset = priv->msg_body->allocation.y;
513 new_value = (offset + rectangle.y);
515 hildon_pannable_area_jump_to (HILDON_PANNABLE_AREA (priv->pannable), -1, new_value);
519 correct_scroll (ModestMsgEditWindow *w)
521 ModestMsgEditWindowPrivate *priv;
523 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
524 if (gtk_grab_get_current () == priv->msg_body) {
525 if (priv->scroll_drag_timeout_id == 0) {
526 priv->scroll_drag_timeout_id = g_timeout_add (500, (GSourceFunc) scroll_drag_timeout,
532 correct_scroll_without_drag_check (w, TRUE);
536 text_buffer_end_user_action (GtkTextBuffer *buffer,
537 ModestMsgEditWindow *userdata)
540 correct_scroll (userdata);
544 text_buffer_mark_set (GtkTextBuffer *buffer,
547 ModestMsgEditWindow *userdata)
549 gtk_text_buffer_begin_user_action (buffer);
550 gtk_text_buffer_end_user_action (buffer);
554 cut_clipboard_check (GtkTextView *text_view,
557 GtkTextBuffer *buffer;
559 buffer = gtk_text_view_get_buffer (text_view);
560 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
561 g_signal_stop_emission_by_name ((gpointer )text_view, "cut-clipboard");
566 copy_clipboard_check (GtkTextView *text_view,
569 GtkTextBuffer *buffer;
571 buffer = gtk_text_view_get_buffer (text_view);
572 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
573 g_signal_stop_emission_by_name ((gpointer )text_view, "copy-clipboard");
578 attachment_deleted (ModestAttachmentsView *attachments_view,
581 modest_msg_edit_window_remove_attachments (MODEST_MSG_EDIT_WINDOW (user_data),
586 connect_signals (ModestMsgEditWindow *obj)
588 ModestMsgEditWindowPrivate *priv;
590 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
592 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
593 G_CALLBACK (text_buffer_refresh_attributes), obj);
594 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
595 G_CALLBACK (text_buffer_can_undo), obj);
596 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
597 G_CALLBACK (text_buffer_can_redo), obj);
598 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
599 G_CALLBACK (body_changed), obj);
600 g_signal_connect (G_OBJECT (priv->text_buffer), "modified-changed",
601 G_CALLBACK (body_changed), obj);
602 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
603 G_CALLBACK (text_buffer_end_user_action), obj);
604 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
605 G_CALLBACK (text_buffer_mark_set), obj);
606 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
607 G_CALLBACK (text_buffer_apply_tag), obj);
608 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
609 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
610 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
611 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
612 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
613 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
615 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
616 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
618 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
619 G_CALLBACK (msg_body_focus), obj);
620 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
621 G_CALLBACK (msg_body_focus), obj);
622 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
623 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
624 "changed", G_CALLBACK (recpt_field_changed), obj);
625 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
626 "changed", G_CALLBACK (recpt_field_changed), obj);
627 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
628 "changed", G_CALLBACK (recpt_field_changed), obj);
629 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
630 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
631 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
633 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
634 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
636 priv->clipboard_change_handler_id =
637 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
638 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
639 priv->default_clipboard_change_handler_id =
640 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
641 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
643 g_signal_connect (G_OBJECT (priv->msg_body), "cut-clipboard", G_CALLBACK (cut_clipboard_check), NULL);
644 g_signal_connect (G_OBJECT (priv->msg_body), "copy-clipboard", G_CALLBACK (copy_clipboard_check), NULL);
645 g_signal_connect (G_OBJECT (priv->attachments_view), "delete", G_CALLBACK (attachment_deleted), obj);
649 init_wp_text_view_style ()
651 static gboolean initialized = FALSE;
654 gtk_rc_parse_string ("class \"WPTextView\" style \"fremantle-textview\"");
660 init_window (ModestMsgEditWindow *obj)
662 GtkWidget *to_caption, *subject_caption;
663 GtkWidget *main_vbox;
664 ModestMsgEditWindowPrivate *priv;
665 GtkActionGroup *action_group;
666 ModestWindowPrivate *parent_priv;
667 GdkPixbuf *window_icon = NULL;
668 GError *error = NULL;
670 GtkSizeGroup *title_size_group;
671 GtkSizeGroup *value_size_group;
672 GtkWidget *subject_box;
673 GtkWidget *attachment_icon;
674 GtkWidget *window_box;
675 #if (GTK_MINOR_VERSION >= 10)
676 GdkAtom deserialize_type;
679 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
680 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
682 parent_priv->ui_manager = gtk_ui_manager_new();
683 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
684 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
686 /* Add common actions */
687 gtk_action_group_add_actions (action_group,
688 modest_msg_edit_action_entries,
689 G_N_ELEMENTS (modest_msg_edit_action_entries),
691 gtk_action_group_add_toggle_actions (action_group,
692 modest_msg_edit_toggle_action_entries,
693 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
695 gtk_action_group_add_radio_actions (action_group,
696 modest_msg_edit_alignment_radio_action_entries,
697 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
699 G_CALLBACK (modest_ui_actions_on_change_justify),
701 gtk_action_group_add_radio_actions (action_group,
702 modest_msg_edit_priority_action_entries,
703 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
705 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
707 gtk_action_group_add_radio_actions (action_group,
708 modest_msg_edit_file_format_action_entries,
709 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
710 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
711 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
713 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
714 g_object_unref (action_group);
716 /* Load the UI definition */
717 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
720 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
721 g_clear_error (&error);
724 /* Add accelerators */
725 gtk_window_add_accel_group (GTK_WINDOW (obj),
726 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
728 parent_priv->menubar = NULL;
730 title_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
731 value_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
733 /* Note: This ModestPairList* must exist for as long as the picker
734 * that uses it, because the ModestSelectorPicker uses the ID opaquely,
735 * so it can't know how to manage its memory. */
736 priv->from_field = modest_selector_picker_new (MODEST_EDITABLE_SIZE,
737 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
739 modest_maemo_utils_set_hbutton_layout (title_size_group, value_size_group,
740 _("mail_va_from"), priv->from_field);
742 priv->to_field = modest_recpt_editor_new ();
743 priv->cc_field = modest_recpt_editor_new ();
744 priv->bcc_field = modest_recpt_editor_new ();
745 subject_box = gtk_hbox_new (FALSE, 0);
746 priv->priority_icon = gtk_image_new ();
747 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
748 priv->subject_field = hildon_entry_new (MODEST_EDITABLE_SIZE);
749 gtk_entry_set_max_length (GTK_ENTRY (priv->subject_field) ,SUBJECT_MAX_LENGTH);
750 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
751 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
752 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
753 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
754 priv->add_attachment_button = gtk_button_new ();
755 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
756 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
757 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
758 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 0.5);
759 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, HILDON_ICON_SIZE_FINGER);
760 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
761 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
762 priv->attachments_view = modest_attachments_view_new (NULL);
764 priv->header_box = gtk_vbox_new (FALSE, 0);
766 to_caption = modest_maemo_utils_create_captioned_with_size_type
767 (title_size_group, value_size_group,
768 _("mail_va_to"), priv->to_field,
769 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
770 priv->cc_caption = modest_maemo_utils_create_captioned_with_size_type
771 (title_size_group, value_size_group,
772 _("mail_va_cc"), priv->cc_field,
773 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
774 priv->bcc_caption = modest_maemo_utils_create_captioned_with_size_type
775 (title_size_group, value_size_group,
776 _("mail_va_hotfix1"), priv->bcc_field,
777 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
778 subject_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
779 _("mail_va_subject"), subject_box);
780 priv->attachments_caption = modest_maemo_utils_create_captioned_with_size_type (title_size_group, value_size_group,
781 _("mail_va_attachment"),
782 priv->attachments_view,
783 HILDON_SIZE_AUTO_WIDTH |
784 HILDON_SIZE_AUTO_HEIGHT);
785 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), value_size_group); */
786 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), value_size_group); */
787 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), value_size_group); */
788 g_object_unref (title_size_group);
789 g_object_unref (value_size_group);
791 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->from_field, FALSE, FALSE, 0);
792 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
793 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
794 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
795 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
796 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
797 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
799 init_wp_text_view_style ();
801 priv->msg_body = wp_text_view_new ();
804 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
805 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
806 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
807 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
808 #if (GTK_MINOR_VERSION >= 10)
809 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), NULL);
810 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
812 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
813 deserialize_type, TRUE);
815 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
817 priv->find_toolbar = hildon_find_toolbar_new (NULL);
818 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
820 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
822 priv->pannable = hildon_pannable_area_new ();
824 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
826 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
827 priv->frame = gtk_frame_new (NULL);
828 gtk_box_pack_start (GTK_BOX(main_vbox), priv->frame, TRUE, TRUE, 0);
830 hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA (priv->pannable), main_vbox);
831 gtk_widget_show_all (GTK_WIDGET(priv->pannable));
833 window_box = gtk_vbox_new (FALSE, 0);
834 gtk_container_add (GTK_CONTAINER(obj), window_box);
836 gtk_box_pack_start (GTK_BOX (window_box), priv->pannable, TRUE, TRUE, 0);
838 gtk_container_add (GTK_CONTAINER (priv->frame), priv->msg_body);
840 /* Set window icon */
841 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
843 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
844 g_object_unref (window_icon);
849 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
851 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
853 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
854 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
855 priv->clipboard_change_handler_id))
856 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
857 priv->clipboard_change_handler_id);
858 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
859 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
860 priv->default_clipboard_change_handler_id))
861 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
862 priv->default_clipboard_change_handler_id);
864 if (priv->account_removed_handler_id &&
865 g_signal_handler_is_connected (modest_runtime_get_account_store (),
866 priv->account_removed_handler_id))
867 g_signal_handler_disconnect(modest_runtime_get_account_store (),
868 priv->account_removed_handler_id);
872 modest_msg_edit_window_finalize (GObject *obj)
874 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
876 /* Sanity check: shouldn't be needed, the window mgr should
877 call this function before */
878 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
880 if (priv->font_dialog != NULL) {
881 gtk_dialog_response (GTK_DIALOG (priv->font_dialog), GTK_RESPONSE_NONE);
884 if (priv->clipboard_text != NULL) {
885 g_free (priv->clipboard_text);
886 priv->clipboard_text = NULL;
889 if (priv->draft_msg != NULL) {
890 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
891 if (TNY_IS_HEADER (header)) {
892 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
893 modest_window_mgr_unregister_header (mgr, header);
895 g_object_unref (priv->draft_msg);
896 priv->draft_msg = NULL;
898 if (priv->outbox_msg != NULL) {
899 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
900 if (TNY_IS_HEADER (header)) {
901 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
902 modest_window_mgr_unregister_header (mgr, header);
904 g_object_unref (priv->outbox_msg);
905 priv->outbox_msg = NULL;
907 if (priv->scroll_drag_timeout_id > 0) {
908 g_source_remove (priv->scroll_drag_timeout_id);
909 priv->scroll_drag_timeout_id = 0;
911 if (priv->clipboard_owner_idle > 0) {
912 g_source_remove (priv->clipboard_owner_idle);
913 priv->clipboard_owner_idle = 0;
915 if (priv->original_account_name)
916 g_free (priv->original_account_name);
917 g_free (priv->msg_uid);
918 g_free (priv->last_search);
919 g_slist_free (priv->font_items_group);
920 g_slist_free (priv->size_items_group);
921 g_object_unref (priv->attachments);
922 g_object_unref (priv->images);
924 /* This had to stay alive for as long as the picker that used it: */
925 modest_pair_list_free (priv->from_field_protos);
927 G_OBJECT_CLASS(parent_class)->finalize (obj);
931 pixbuf_from_stream (TnyStream *stream, const gchar *mime_type, guint64 *stream_size)
933 GdkPixbufLoader *loader;
939 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
941 if (loader == NULL) {
947 tny_stream_reset (TNY_STREAM (stream));
948 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
949 GError *error = NULL;
950 unsigned char read_buffer[128];
952 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
954 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, &error)) {
956 g_error_free (error);
961 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
963 g_object_ref (pixbuf);
964 gdk_pixbuf_loader_close (loader, NULL);
965 g_object_unref (loader);
970 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
971 GdkPixbuf *new_pixbuf;
973 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
974 gdk_pixbuf_get_width (pixbuf);
975 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
976 g_object_unref (pixbuf);
987 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
989 ModestMsgEditWindowPrivate *priv;
992 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
994 for (iter = tny_list_create_iterator (attachments);
995 !tny_iterator_is_done (iter);
996 tny_iterator_next (iter)) {
997 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
998 const gchar *cid = tny_mime_part_get_content_id (part);
999 const gchar *mime_type = tny_mime_part_get_content_type (part);
1000 if ((cid != NULL)&&(mime_type != NULL)) {
1001 guint64 stream_size;
1002 TnyStream *stream = tny_mime_part_get_decoded_stream (part);
1003 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
1006 g_object_unref (stream);
1008 if (pixbuf != NULL) {
1009 priv->images_count ++;
1010 priv->images_size += stream_size;
1011 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1012 g_object_unref (pixbuf);
1015 g_object_unref (part);
1017 g_object_unref (iter);
1021 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1023 TnyMimePart *parent = NULL;
1024 const gchar *content_type = NULL;
1025 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1027 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1029 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1030 parent = g_object_ref (msg);
1031 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1032 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1035 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1036 iter = tny_list_create_iterator (parts);
1037 while (!tny_iterator_is_done (iter)) {
1039 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1040 content_type = tny_mime_part_get_content_type (part);
1041 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1045 g_object_unref (part);
1047 tny_iterator_next (iter);
1049 g_object_unref (iter);
1050 g_object_unref (parts);
1053 if (parent != NULL) {
1054 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1057 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1058 iter = tny_list_create_iterator (parts);
1059 while (!tny_iterator_is_done (iter)) {
1061 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1062 content_type = tny_mime_part_get_content_type (part);
1063 if (content_type && g_str_has_prefix (content_type, "image/")) {
1064 tny_list_prepend (priv->images, (GObject *) part);
1066 g_object_unref (part);
1067 tny_iterator_next (iter);
1069 g_object_unref (iter);
1070 g_object_unref (parts);
1071 g_object_unref (parent);
1076 update_next_cid (ModestMsgEditWindow *self, TnyList *attachments)
1079 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1081 for (iter = tny_list_create_iterator (attachments) ;
1082 !tny_iterator_is_done (iter);
1083 tny_iterator_next (iter)) {
1084 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1085 const gchar *cid = tny_mime_part_get_content_id (part);
1087 char *invalid = NULL;
1088 gint int_cid = strtol (cid, &invalid, 10);
1089 if ((invalid != NULL) && (*invalid == '\0') && (int_cid >= priv->next_cid)) {
1090 priv->next_cid = int_cid + 1;
1093 g_object_unref (part);
1095 g_object_unref (iter);
1099 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1102 gchar *to, *cc, *bcc, *subject;
1104 ModestMsgEditWindowPrivate *priv;
1105 ModestWindowPrivate *parent_priv;
1107 TnyHeaderFlags priority_flags;
1108 TnyFolder *msg_folder;
1109 gboolean is_html = FALSE;
1111 gboolean field_view_set;
1113 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1114 g_return_if_fail (TNY_IS_MSG (msg));
1116 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1117 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1119 header = tny_msg_get_header (msg);
1120 to = tny_header_dup_to (header);
1121 cc = tny_header_dup_cc (header);
1122 bcc = tny_header_dup_bcc (header);
1123 subject = tny_header_dup_subject (header);
1124 priority_flags = tny_header_get_priority (header);
1127 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1129 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
1130 field_view_set = TRUE;
1132 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1133 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1134 gtk_widget_show (priv->cc_caption);
1135 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1136 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1137 gtk_widget_hide (priv->cc_caption);
1138 field_view_set = FALSE;
1141 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), field_view_set);
1143 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
1144 field_view_set = TRUE;
1146 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1147 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1148 gtk_widget_show (priv->bcc_caption);
1149 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1150 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1151 gtk_widget_hide (priv->bcc_caption);
1152 field_view_set = FALSE;
1155 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), field_view_set);
1159 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1160 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1163 update_window_title (self);
1165 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1166 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1168 if ((body == NULL)||(body[0] == '\0')) {
1170 body = modest_text_utils_convert_to_html ("");
1173 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1174 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1177 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1180 /* Add attachments to the view */
1181 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1182 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1183 if (tny_list_get_length (priv->attachments) == 0) {
1184 gtk_widget_hide (priv->attachments_caption);
1186 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1187 gtk_widget_show_all (priv->attachments_caption);
1189 get_related_images (self, msg);
1190 update_next_cid (self, priv->attachments);
1191 update_next_cid (self, priv->images);
1192 replace_with_images (self, priv->images);
1194 if (preserve_is_rich && !is_html) {
1195 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1196 /* Get the default format required from configuration */
1197 } else if (!preserve_is_rich && !modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1198 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1201 /* Set the default focus depending on having already a To: field or not */
1202 if ((!to)||(*to == '\0')) {
1203 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1205 gtk_widget_grab_focus (priv->msg_body);
1208 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1210 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1211 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1213 modest_msg_edit_window_set_modified (self, FALSE);
1215 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1216 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1217 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1218 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1220 if (priv->msg_uid) {
1221 g_free (priv->msg_uid);
1222 priv->msg_uid = NULL;
1225 /* we should set a reference to the incoming message if it is a draft */
1226 msg_folder = tny_msg_get_folder (msg);
1228 if (modest_tny_folder_is_local_folder (msg_folder)) {
1229 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1230 if (type == TNY_FOLDER_TYPE_INVALID)
1231 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1233 if (type == TNY_FOLDER_TYPE_DRAFTS)
1234 priv->draft_msg = g_object_ref(msg);
1235 if (type == TNY_FOLDER_TYPE_OUTBOX)
1236 priv->outbox_msg = g_object_ref(msg);
1237 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1239 g_object_unref (msg_folder);
1249 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
1252 GList *item_children, *node;
1253 GtkWidget *bin_child;
1255 bin_child = gtk_bin_get_child (GTK_BIN(item));
1257 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
1259 for (node = item_children; node != NULL; node = g_list_next (node)) {
1260 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
1261 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
1264 g_list_free (item_children);
1268 menu_tool_button_dont_expand (GtkMenuToolButton *item)
1271 GList *item_children, *node;
1273 box = gtk_bin_get_child (GTK_BIN (item));
1274 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
1275 item_children = gtk_container_get_children (GTK_CONTAINER (box));
1277 for (node = item_children; node != NULL; node = g_list_next (node)) {
1278 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
1279 if (GTK_IS_TOGGLE_BUTTON (node->data))
1280 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
1281 else if (GTK_IS_BUTTON (node->data))
1282 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
1284 g_list_free (item_children);
1289 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1291 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1292 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1293 GtkWidget *placeholder;
1294 GtkWidget *tool_item;
1299 GtkWidget *sizes_menu;
1300 GtkWidget *fonts_menu;
1301 GSList *radio_group = NULL;
1302 GSList *node = NULL;
1306 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1307 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1309 /* Font color placeholder */
1310 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1311 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1314 priv->font_color_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1315 priv->font_color_button = hildon_color_button_new ();
1316 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
1317 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1318 gtk_container_add (GTK_CONTAINER (priv->font_color_toolitem), priv->font_color_button);
1319 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1320 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1321 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->font_color_toolitem), insert_index);
1322 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1324 G_CALLBACK (modest_msg_edit_window_color_button_change),
1327 /* Font size and face placeholder */
1328 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1329 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1331 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1332 priv->size_tool_button_label = gtk_label_new (NULL);
1333 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1334 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1335 size_text,"</span>", NULL);
1336 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1338 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
1339 sizes_menu = gtk_menu_new ();
1340 priv->size_items_group = NULL;
1342 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1343 GtkWidget *size_menu_item;
1345 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1346 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
1347 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
1348 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
1349 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
1350 gtk_widget_show (size_menu_item);
1352 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
1356 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1357 GtkWidget *item = (GtkWidget *) node->data;
1358 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
1362 priv->size_items_group = g_slist_reverse (priv->size_items_group);
1363 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
1364 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1365 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1366 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1367 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1368 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1369 priv->font_size_toolitem = tool_item;
1372 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1373 priv->font_tool_button_label = gtk_label_new (NULL);
1374 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1375 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1377 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
1378 fonts_menu = gtk_menu_new ();
1379 priv->font_items_group = NULL;
1381 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1382 GtkWidget *font_menu_item;
1383 GtkWidget *child_label;
1385 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
1386 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
1387 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
1388 wp_get_font_name (font_index), "</span>", NULL);
1389 gtk_label_set_markup (GTK_LABEL (child_label), markup);
1392 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
1393 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
1394 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
1395 gtk_widget_show (font_menu_item);
1397 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
1400 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1401 GtkWidget *item = (GtkWidget *) node->data;
1402 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
1405 priv->font_items_group = g_slist_reverse (priv->font_items_group);
1406 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
1407 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1408 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1409 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1410 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1411 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1412 priv->font_face_toolitem = tool_item;
1414 /* Set expand and homogeneous for remaining items */
1415 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1416 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1417 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1418 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1419 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1420 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1421 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1422 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1423 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1425 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1426 will not show the tool items added to the placeholders) */
1427 gtk_widget_show_all (parent_priv->toolbar);
1429 /* Set the no show all *after* showing all items. We do not
1430 want the toolbar to be shown with a show all because it
1431 could go agains the gconf setting regarding showing or not
1432 the toolbar of the editor window */
1433 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1439 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean preserve_is_rich)
1442 ModestWindowPrivate *parent_priv;
1443 ModestMsgEditWindowPrivate *priv;
1444 ModestDimmingRulesGroup *menu_rules_group = NULL;
1445 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1446 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1447 ModestWindowMgr *mgr = NULL;
1449 g_return_val_if_fail (msg, NULL);
1450 g_return_val_if_fail (account_name, NULL);
1452 mgr = modest_runtime_get_window_mgr ();
1454 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1456 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1457 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1459 /* Menubar. Update the state of some toggles */
1460 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1461 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
1462 priv->from_field_protos = get_transports ();
1463 modest_selector_picker_set_pair_list (MODEST_SELECTOR_PICKER (priv->from_field), priv->from_field_protos);
1464 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1465 hildon_button_set_title (HILDON_BUTTON (priv->from_field),
1467 hildon_button_set_value (HILDON_BUTTON (priv->from_field),
1468 hildon_touch_selector_get_current_text
1469 (HILDON_TOUCH_SELECTOR (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (priv->from_field)))));
1470 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1471 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1474 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1476 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1478 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1480 priv->original_account_name = (account_name) ? g_strdup (account_name) : NULL;
1482 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new ();
1483 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1484 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1485 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1486 /* Add common dimming rules */
1487 modest_dimming_rules_group_add_rules (menu_rules_group,
1488 modest_msg_edit_window_menu_dimming_entries,
1489 G_N_ELEMENTS (modest_msg_edit_window_menu_dimming_entries),
1490 MODEST_WINDOW (obj));
1491 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1492 modest_msg_edit_window_toolbar_dimming_entries,
1493 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1494 MODEST_WINDOW (obj));
1495 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_toolitem,
1496 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1497 MODEST_WINDOW (obj));
1498 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1499 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1500 MODEST_WINDOW (obj));
1501 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1502 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1503 MODEST_WINDOW (obj));
1504 /* Insert dimming rules group for this window */
1505 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1506 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1507 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1508 /* Checks the dimming rules */
1509 g_object_unref (menu_rules_group);
1510 g_object_unref (toolbar_rules_group);
1511 g_object_unref (clipboard_rules_group);
1512 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1514 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1516 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1517 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1518 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1519 priv->update_caption_visibility = TRUE;
1521 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1523 /* Track account-removed signal, this window should be closed
1524 in the case we're creating a mail associated to the account
1526 priv->account_removed_handler_id =
1527 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1529 G_CALLBACK(on_account_removed),
1532 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (MODEST_MSG_EDIT_WINDOW (obj));
1534 return (ModestWindow*) obj;
1538 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1540 GString **string_buffer = (GString **) user_data;
1542 *string_buffer = g_string_append (*string_buffer, buffer);
1548 * @result: A new string which should be freed with g_free().
1551 get_formatted_data (ModestMsgEditWindow *edit_window)
1553 ModestMsgEditWindowPrivate *priv;
1554 GString *string_buffer = g_string_new ("");
1556 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1558 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1560 modest_text_utils_hyperlinkify (string_buffer);
1562 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1564 return g_string_free (string_buffer, FALSE);
1569 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1572 const gchar *account_name;
1573 ModestMsgEditWindowPrivate *priv;
1574 TnyIterator *att_iter;
1576 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1578 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1580 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1581 g_return_val_if_fail (account_name, NULL);
1584 /* don't free these (except from) */
1585 data = g_slice_new0 (MsgData);
1586 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1588 data->account_name = g_strdup (account_name);
1589 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1590 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1591 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1592 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1593 if (priv->draft_msg) {
1594 data->draft_msg = g_object_ref (priv->draft_msg);
1595 } else if (priv->outbox_msg) {
1596 data->draft_msg = g_object_ref (priv->outbox_msg);
1598 data->draft_msg = NULL;
1601 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1603 gtk_text_buffer_get_bounds (buf, &b, &e);
1604 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1606 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1607 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1609 data->html_body = NULL;
1611 /* deep-copy the data */
1612 att_iter = tny_list_create_iterator (priv->attachments);
1613 data->attachments = NULL;
1614 while (!tny_iterator_is_done (att_iter)) {
1615 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1616 if (!(TNY_IS_MIME_PART(part))) {
1617 g_warning ("strange data in attachment list");
1618 g_object_unref (part);
1619 tny_iterator_next (att_iter);
1622 data->attachments = g_list_append (data->attachments,
1624 tny_iterator_next (att_iter);
1626 g_object_unref (att_iter);
1628 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1629 att_iter = tny_list_create_iterator (priv->images);
1630 data->images = NULL;
1631 while (!tny_iterator_is_done (att_iter)) {
1632 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1634 if (!(TNY_IS_MIME_PART(part))) {
1635 g_warning ("strange data in attachment list");
1636 g_object_unref (part);
1637 tny_iterator_next (att_iter);
1640 cid = tny_mime_part_get_content_id (part);
1642 gchar *image_tag_id;
1643 GtkTextTag *image_tag;
1645 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1646 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1647 g_free (image_tag_id);
1649 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1651 ((gtk_text_iter_has_tag (&iter, image_tag))||
1652 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1653 data->images = g_list_append (data->images,
1654 g_object_ref (part));
1656 g_object_unref (part);
1657 tny_iterator_next (att_iter);
1659 g_object_unref (att_iter);
1661 data->priority_flags = priv->priority_flags;
1668 unref_gobject (GObject *obj, gpointer data)
1670 if (!G_IS_OBJECT(obj))
1672 g_object_unref (obj);
1676 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1679 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1687 g_free (data->from);
1688 g_free (data->subject);
1689 g_free (data->plain_body);
1690 g_free (data->html_body);
1691 g_free (data->account_name);
1693 if (data->draft_msg != NULL) {
1694 g_object_unref (data->draft_msg);
1695 data->draft_msg = NULL;
1698 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1699 g_list_free (data->attachments);
1700 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1701 g_list_free (data->images);
1703 g_slice_free (MsgData, data);
1707 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1709 guint64 *parts_size)
1711 ModestMsgEditWindowPrivate *priv;
1713 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1715 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1717 /* TODO: add images */
1718 *parts_size += priv->images_size;
1719 *parts_count += priv->images_count;
1724 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1727 ModestMsgEditWindowPrivate *priv = NULL;
1728 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1730 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1732 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1734 return MODEST_MSG_EDIT_FORMAT_HTML;
1736 return MODEST_MSG_EDIT_FORMAT_TEXT;
1740 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1741 ModestMsgEditFormat format)
1743 ModestMsgEditWindowPrivate *priv;
1745 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1746 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1749 case MODEST_MSG_EDIT_FORMAT_HTML:
1750 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1752 case MODEST_MSG_EDIT_FORMAT_TEXT:
1753 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1756 g_return_if_reached ();
1760 ModestMsgEditFormatState *
1761 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1763 ModestMsgEditFormatState *format_state = NULL;
1764 ModestMsgEditWindowPrivate *priv;
1765 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1767 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1768 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1770 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1772 format_state = g_new0 (ModestMsgEditFormatState, 1);
1773 format_state->bold = buffer_format->bold&0x1;
1774 format_state->italics = buffer_format->italic&0x1;
1775 format_state->bullet = buffer_format->bullet&0x1;
1776 format_state->color = buffer_format->color;
1777 format_state->font_size = buffer_format->font_size;
1778 format_state->font_family = wp_get_font_name (buffer_format->font);
1779 format_state->justification = buffer_format->justification;
1780 g_free (buffer_format);
1782 return format_state;
1787 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1788 const ModestMsgEditFormatState *format_state)
1790 ModestMsgEditWindowPrivate *priv;
1791 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1792 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1793 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1794 g_return_if_fail (format_state != NULL);
1796 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1797 gtk_widget_grab_focus (priv->msg_body);
1798 buffer_format->bold = (format_state->bold != FALSE);
1799 buffer_format->italic = (format_state->italics != FALSE);
1800 buffer_format->color = format_state->color;
1801 buffer_format->font_size = format_state->font_size;
1802 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1803 buffer_format->justification = format_state->justification;
1804 buffer_format->bullet = format_state->bullet;
1806 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1808 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1809 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1810 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1811 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1812 buffer_format->cs.font = (buffer_format->font != current_format->font);
1813 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1814 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1816 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1817 if (buffer_format->cs.bold) {
1818 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1819 GINT_TO_POINTER (buffer_format->bold&0x1));
1821 if (buffer_format->cs.italic) {
1822 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1823 GINT_TO_POINTER (buffer_format->italic&0x1));
1825 if (buffer_format->cs.color) {
1826 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1827 GINT_TO_POINTER (&(buffer_format->color)));
1829 if (buffer_format->cs.font_size) {
1830 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1831 GINT_TO_POINTER (buffer_format->font_size));
1833 if (buffer_format->cs.justification) {
1834 switch (buffer_format->justification) {
1835 case GTK_JUSTIFY_LEFT:
1836 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1837 GINT_TO_POINTER(TRUE));
1839 case GTK_JUSTIFY_CENTER:
1840 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1841 GINT_TO_POINTER(TRUE));
1843 case GTK_JUSTIFY_RIGHT:
1844 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1845 GINT_TO_POINTER(TRUE));
1852 if (buffer_format->cs.font) {
1853 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1854 GINT_TO_POINTER (buffer_format->font));
1856 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1857 if (buffer_format->cs.bullet) {
1858 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
1859 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
1861 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1863 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
1865 g_free (buffer_format);
1866 g_free (current_format);
1868 /* Check dimming rules */
1869 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1870 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1874 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1876 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1878 ModestWindowPrivate *parent_priv;
1879 ModestMsgEditWindowPrivate *priv;
1880 GtkWidget *new_size_menuitem;
1881 GtkWidget *new_font_menuitem;
1883 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1884 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1886 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1887 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu");
1888 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1889 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1891 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatPlainTextMenu");
1892 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1893 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1896 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1898 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1899 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1901 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1902 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1904 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
1905 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
1908 switch (buffer_format->justification)
1910 case GTK_JUSTIFY_LEFT:
1911 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1913 case GTK_JUSTIFY_CENTER:
1914 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1916 case GTK_JUSTIFY_RIGHT:
1917 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1924 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1926 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1927 G_CALLBACK (modest_msg_edit_window_color_button_change),
1929 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1930 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1931 G_CALLBACK (modest_msg_edit_window_color_button_change),
1934 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1935 buffer_format->font_size))->data);
1936 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1940 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1941 markup = g_strconcat ("<span font_family='Sans'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1942 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1944 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1945 G_CALLBACK (modest_msg_edit_window_size_change),
1947 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1948 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1949 G_CALLBACK (modest_msg_edit_window_size_change),
1953 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1954 buffer_format->font))->data);
1955 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1959 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1960 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1961 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1963 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1964 G_CALLBACK (modest_msg_edit_window_font_change),
1966 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1967 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1968 G_CALLBACK (modest_msg_edit_window_font_change),
1972 g_free (buffer_format);
1976 #ifdef MODEST_HILDON_VERSION_0
1978 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1981 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1982 ModestMsgEditWindowPrivate *priv;
1983 GtkWidget *dialog = NULL;
1985 GdkColor *new_color = NULL;
1987 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1988 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1990 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1991 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1992 g_free (buffer_format);
1994 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
1995 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1996 if (new_color != NULL) {
1997 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1998 (gpointer) new_color);
2001 gtk_widget_destroy (dialog);
2006 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2009 ModestMsgEditWindowPrivate *priv;
2010 GtkWidget *dialog = NULL;
2012 GdkColor *old_color = NULL;
2013 const GdkColor *new_color = NULL;
2015 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2016 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2018 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2019 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2021 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2022 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2023 if (new_color != NULL)
2024 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2026 gtk_widget_destroy (dialog);
2032 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2035 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2036 ModestMsgEditWindowPrivate *priv;
2037 GtkWidget *dialog = NULL;
2039 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2040 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2042 dialog = hildon_color_chooser_new ();
2043 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2044 g_free (buffer_format);
2046 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2048 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2049 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2052 gtk_widget_destroy (dialog);
2057 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2060 ModestMsgEditWindowPrivate *priv;
2061 GtkWidget *dialog = NULL;
2062 GdkColor *old_color = NULL;
2064 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2065 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2067 dialog = hildon_color_chooser_new ();
2068 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2070 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2072 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2073 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2075 gtk_widget_destroy (dialog);
2078 #endif /*!MODEST_HILDON_VERSION_0*/
2083 create_stream_for_uri (const gchar* uri)
2088 TnyStream *result = NULL;
2090 GnomeVFSHandle *handle = NULL;
2091 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2092 if (test == GNOME_VFS_OK) {
2093 TnyStream *vfssstream = TNY_STREAM (tny_vfs_stream_new (handle));
2094 /* Streams over OBEX (Bluetooth) are not seekable but
2095 * we expect them to be (we might need to read them
2096 * several times). So if this is a Bluetooth URI just
2097 * read the whole file into memory (this is not a fast
2098 * protocol so we can assume that these files are not
2099 * going to be very big) */
2100 if ((g_ascii_strncasecmp (uri, "obex://", 7) == 0)||
2101 (g_ascii_strncasecmp (uri, "upnpav://", 9) == 0)) {
2102 TnyStream *memstream = tny_camel_mem_stream_new ();
2103 tny_stream_write_to_stream (vfssstream, memstream);
2104 g_object_unref (vfssstream);
2107 result = vfssstream;
2115 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2118 ModestMsgEditWindowPrivate *priv;
2119 GtkWidget *dialog = NULL;
2121 GSList *uris = NULL;
2122 GSList *uri_node = NULL;
2124 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2126 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2127 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2128 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2130 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2132 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2133 GTK_WINDOW (dialog), GTK_WINDOW (window));
2135 response = gtk_dialog_run (GTK_DIALOG (dialog));
2137 case GTK_RESPONSE_OK:
2138 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2143 gtk_widget_destroy (dialog);
2145 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2147 GnomeVFSHandle *handle = NULL;
2148 GnomeVFSResult result;
2149 GtkTextIter position;
2150 GtkTextMark *insert_mark;
2152 uri = (const gchar *) uri_node->data;
2153 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2154 if (result == GNOME_VFS_OK) {
2156 GnomeVFSFileInfo *info;
2157 gchar *filename, *basename, *escaped_filename;
2158 TnyMimePart *mime_part;
2160 const gchar *mime_type = NULL;
2161 GnomeVFSURI *vfs_uri;
2162 guint64 stream_size;
2164 gnome_vfs_close (handle);
2165 vfs_uri = gnome_vfs_uri_new (uri);
2167 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2168 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2169 g_free (escaped_filename);
2170 gnome_vfs_uri_unref (vfs_uri);
2171 info = gnome_vfs_file_info_new ();
2173 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2174 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2176 mime_type = gnome_vfs_file_info_get_mime_type (info);
2178 mime_part = tny_platform_factory_new_mime_part
2179 (modest_runtime_get_platform_factory ());
2181 TnyStream *stream = create_stream_for_uri (uri);
2183 if (stream == NULL) {
2185 modest_platform_information_banner (NULL, NULL, dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2187 g_object_unref (mime_part);
2188 gnome_vfs_file_info_unref (info);
2192 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2194 content_id = g_strdup_printf ("%d", priv->next_cid);
2195 tny_mime_part_set_content_id (mime_part, content_id);
2196 g_free (content_id);
2199 basename = g_path_get_basename (filename);
2200 tny_mime_part_set_filename (mime_part, basename);
2203 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
2205 if (pixbuf != NULL) {
2206 priv->images_size += stream_size;
2207 priv->images_count ++;
2208 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2209 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2210 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
2211 g_object_unref (pixbuf);
2214 tny_list_prepend (priv->images, (GObject *) mime_part);
2215 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2217 g_object_unref (mime_part);
2218 gnome_vfs_file_info_unref (info);
2227 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2229 GtkWidget *dialog = NULL;
2231 GSList *uris = NULL;
2233 GnomeVFSFileSize total_size, allowed_size;
2234 ModestMsgEditWindowPrivate *priv;
2238 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(window));
2240 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2242 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2245 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2246 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2247 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2248 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), GTK_WINDOW (window));
2250 response = gtk_dialog_run (GTK_DIALOG (dialog));
2252 case GTK_RESPONSE_OK:
2253 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2258 gtk_widget_destroy (dialog);
2260 /* allowed size is the maximum size - what's already there */
2261 modest_attachments_view_get_sizes (
2262 MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2263 &att_num, &att_size);
2264 allowed_size = MODEST_MAX_ATTACHMENT_SIZE - att_size;
2267 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2269 const gchar *uri = (const gchar *) uri_node->data;
2271 total_size += modest_msg_edit_window_attach_file_one
2272 (window, uri, allowed_size);
2274 if (total_size > allowed_size) {
2275 g_warning ("%s: total size: %u",
2276 __FUNCTION__, (unsigned int)total_size);
2280 allowed_size -= total_size;
2284 g_slist_foreach (uris, (GFunc) g_free, NULL);
2285 g_slist_free (uris);
2290 modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window,
2292 GnomeVFSFileSize allowed_size)
2295 GnomeVFSHandle *handle = NULL;
2296 ModestMsgEditWindowPrivate *priv;
2297 GnomeVFSResult result;
2298 GnomeVFSFileSize size = 0;
2299 g_return_val_if_fail (window, 0);
2300 g_return_val_if_fail (uri, 0);
2302 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2304 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2305 if (result == GNOME_VFS_OK) {
2306 TnyMimePart *mime_part;
2308 const gchar *mime_type = NULL;
2310 gchar *escaped_filename;
2313 GnomeVFSFileInfo *info;
2314 GnomeVFSURI *vfs_uri;
2316 gnome_vfs_close (handle);
2317 vfs_uri = gnome_vfs_uri_new (uri);
2320 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2321 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2322 g_free (escaped_filename);
2323 gnome_vfs_uri_unref (vfs_uri);
2325 info = gnome_vfs_file_info_new ();
2327 if (gnome_vfs_get_file_info (uri,
2329 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2331 mime_type = gnome_vfs_file_info_get_mime_type (info);
2332 mime_part = tny_platform_factory_new_mime_part
2333 (modest_runtime_get_platform_factory ());
2335 /* try to get the attachment's size; this may fail for weird
2336 * file systems, like obex, upnp... */
2337 if (allowed_size != 0 &&
2338 info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
2340 if (size > allowed_size) {
2341 modest_platform_information_banner (NULL, NULL,
2342 dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2346 g_warning ("%s: could not get attachment size", __FUNCTION__);
2348 stream = create_stream_for_uri (uri);
2350 if (stream == NULL) {
2352 modest_platform_information_banner (NULL, NULL, dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2354 g_object_unref (mime_part);
2355 gnome_vfs_file_info_unref (info);
2359 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2360 g_object_unref (stream);
2362 content_id = g_strdup_printf ("%d", priv->next_cid);
2363 tny_mime_part_set_content_id (mime_part, content_id);
2364 g_free (content_id);
2367 basename = g_path_get_basename (filename);
2368 tny_mime_part_set_filename (mime_part, basename);
2371 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2372 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2374 info->size == 0, info->size);
2375 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2376 gtk_widget_show_all (priv->attachments_caption);
2377 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2379 g_object_unref (mime_part);
2380 gnome_vfs_file_info_unref (info);
2387 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2390 ModestMsgEditWindowPrivate *priv;
2393 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2394 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2396 if (att_list == NULL) {
2397 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2399 g_object_ref (att_list);
2402 if (tny_list_get_length (att_list) == 0) {
2403 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2405 gboolean dialog_response;
2406 gchar *message = NULL;
2407 gchar *filename = NULL;
2409 if (tny_list_get_length (att_list) == 1) {
2411 iter = tny_list_create_iterator (att_list);
2412 part = (TnyMimePart *) tny_iterator_get_current (iter);
2413 g_object_unref (iter);
2414 if (TNY_IS_MSG (part)) {
2415 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2417 filename = tny_header_dup_subject (header);
2418 g_object_unref (header);
2420 if (filename == NULL) {
2421 filename = g_strdup (_("mail_va_no_subject"));
2424 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2426 g_object_unref (part);
2428 filename = g_strdup ("");
2430 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
2431 tny_list_get_length (att_list)), filename);
2434 dialog_response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window), message);
2437 if (dialog_response != GTK_RESPONSE_OK) {
2438 g_object_unref (att_list);
2441 hildon_banner_show_information (NULL, NULL, _("mcen_me_inbox_remove_attachments"));
2443 for (iter = tny_list_create_iterator (att_list);
2444 !tny_iterator_is_done (iter);
2445 tny_iterator_next (iter)) {
2446 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2447 const gchar *att_id;
2448 tny_list_remove (priv->attachments, (GObject *) mime_part);
2450 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2452 if (tny_list_get_length (priv->attachments) == 0)
2453 gtk_widget_hide (priv->attachments_caption);
2454 att_id = tny_mime_part_get_content_id (mime_part);
2456 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2458 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2459 g_object_unref (mime_part);
2461 g_object_unref (iter);
2464 g_object_unref (att_list);
2466 /* if the last attachment has been removed, focus the Subject: field */
2467 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2468 gtk_widget_grab_focus (priv->subject_field);
2472 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2475 ModestMsgEditWindowPrivate *priv;
2476 GdkColor *new_color;
2477 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2479 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2480 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2483 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2485 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2487 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2489 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2494 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
2497 ModestMsgEditWindowPrivate *priv;
2498 gint new_size_index;
2499 ModestMsgEditWindow *window;
2502 window = MODEST_MSG_EDIT_WINDOW (userdata);
2503 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2504 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2506 if (gtk_check_menu_item_get_active (menu_item)) {
2508 WPTextBufferFormat format;
2510 memset (&format, 0, sizeof (format));
2511 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2513 label = gtk_bin_get_child (GTK_BIN (menu_item));
2515 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
2516 format.cs.font_size = TRUE;
2517 format.cs.text_position = TRUE;
2518 format.cs.font = TRUE;
2519 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
2520 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2522 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2523 GINT_TO_POINTER (wp_get_font_size_index (new_size_index, 12))))
2524 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2526 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2527 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
2528 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2534 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
2537 ModestMsgEditWindowPrivate *priv;
2538 gint new_font_index;
2539 ModestMsgEditWindow *window;
2542 window = MODEST_MSG_EDIT_WINDOW (userdata);
2543 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2544 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2546 if (gtk_check_menu_item_get_active (menu_item)) {
2549 label = gtk_bin_get_child (GTK_BIN (menu_item));
2551 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
2553 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2554 GINT_TO_POINTER(new_font_index)))
2555 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2557 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2558 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2559 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2565 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2568 ModestMsgEditWindowPrivate *priv = NULL;
2569 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2571 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2572 if (!priv->update_caption_visibility)
2575 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2577 gtk_widget_show (priv->cc_caption);
2579 gtk_widget_hide (priv->cc_caption);
2581 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2585 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2588 ModestMsgEditWindowPrivate *priv = NULL;
2589 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2591 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2592 if (!priv->update_caption_visibility)
2595 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2597 gtk_widget_show (priv->bcc_caption);
2599 gtk_widget_hide (priv->bcc_caption);
2601 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2605 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2606 ModestRecptEditor *editor)
2608 ModestMsgEditWindowPrivate *priv;
2610 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2611 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2613 /* we check for low-mem; in that case, show a warning, and don't allow
2614 * for the addressbook
2616 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2619 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2621 if (editor == NULL) {
2622 GtkWidget *view_focus;
2623 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2625 /* This code should be kept in sync with ModestRecptEditor. The
2626 textview inside the recpt editor is the one that really gets the
2627 focus. As it's inside a scrolled window, and this one inside the
2628 hbox recpt editor inherits from, we'll need to go up in the
2629 hierarchy to know if the text view is part of the recpt editor
2630 or if it's a different text entry */
2632 if (gtk_widget_get_parent (view_focus)) {
2633 GtkWidget *first_parent;
2635 first_parent = gtk_widget_get_parent (view_focus);
2636 if (gtk_widget_get_parent (first_parent) &&
2637 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2638 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2643 editor = MODEST_RECPT_EDITOR (priv->to_field);
2647 modest_address_book_select_addresses (editor);
2652 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2654 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2656 modest_msg_edit_window_open_addressbook (window, NULL);
2660 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2661 gboolean show_toolbar)
2663 ModestWindowPrivate *parent_priv;
2665 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2666 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2668 /* We can not just use the code of
2669 modest_msg_edit_window_setup_toolbar because it has a
2670 mixture of both initialization and creation code. */
2672 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2674 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2678 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2679 TnyHeaderFlags priority_flags)
2681 ModestMsgEditWindowPrivate *priv;
2682 ModestWindowPrivate *parent_priv;
2684 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2686 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2687 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2689 if (priv->priority_flags != priority_flags) {
2690 GtkAction *priority_action = NULL;
2692 priv->priority_flags = priority_flags;
2694 switch (priority_flags) {
2695 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2696 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2697 MODEST_HEADER_ICON_HIGH,
2698 HILDON_ICON_SIZE_XSMALL);
2699 gtk_widget_show (priv->priority_icon);
2700 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2701 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2703 case TNY_HEADER_FLAG_LOW_PRIORITY:
2704 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2705 MODEST_HEADER_ICON_LOW,
2706 HILDON_ICON_SIZE_XSMALL);
2707 gtk_widget_show (priv->priority_icon);
2708 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2709 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2712 gtk_widget_hide (priv->priority_icon);
2713 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2714 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2717 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2718 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2723 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2726 ModestMsgEditWindowPrivate *priv;
2727 ModestWindowPrivate *parent_priv;
2728 gint current_format;
2730 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2732 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2733 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2735 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2736 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2738 if (current_format != file_format) {
2739 switch (file_format) {
2740 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2741 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2742 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
2744 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2748 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2749 response = gtk_dialog_run (GTK_DIALOG (dialog));
2750 gtk_widget_destroy (dialog);
2751 if (response == GTK_RESPONSE_OK) {
2752 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2754 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu"));
2755 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
2760 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2761 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2762 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2767 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2770 ModestMsgEditWindowPrivate *priv;
2771 WPTextBufferFormat oldfmt, fmt;
2772 gint old_position = 0;
2776 GdkColor *color = NULL;
2777 gboolean bold, bold_set, italic, italic_set;
2778 gboolean underline, underline_set;
2779 gboolean strikethrough, strikethrough_set;
2780 gboolean position_set;
2781 gboolean font_size_set, font_set, color_set;
2784 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2785 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2787 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2788 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(),
2789 GTK_WINDOW(dialog), GTK_WINDOW (window));
2791 /* First we get the currently selected font information */
2792 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2794 switch (oldfmt.text_position) {
2795 case TEXT_POSITION_NORMAL:
2798 case TEXT_POSITION_SUPERSCRIPT:
2806 g_object_set (G_OBJECT (dialog),
2807 "bold", oldfmt.bold != FALSE,
2808 "bold-set", !oldfmt.cs.bold,
2809 "underline", oldfmt.underline != FALSE,
2810 "underline-set", !oldfmt.cs.underline,
2811 "italic", oldfmt.italic != FALSE,
2812 "italic-set", !oldfmt.cs.italic,
2813 "strikethrough", oldfmt.strikethrough != FALSE,
2814 "strikethrough-set", !oldfmt.cs.strikethrough,
2815 "color", &oldfmt.color,
2816 "color-set", !oldfmt.cs.color,
2817 "size", wp_font_size[oldfmt.font_size],
2818 "size-set", !oldfmt.cs.font_size,
2819 "position", old_position,
2820 "position-set", !oldfmt.cs.text_position,
2821 "family", wp_get_font_name (oldfmt.font),
2822 "family-set", !oldfmt.cs.font,
2825 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2826 GTK_WINDOW (dialog), GTK_WINDOW (window));
2827 gtk_widget_show_all (dialog);
2828 priv->font_dialog = dialog;
2829 response = gtk_dialog_run (GTK_DIALOG (dialog));
2830 priv->font_dialog = NULL;
2831 if (response == GTK_RESPONSE_OK) {
2833 g_object_get( dialog,
2835 "bold-set", &bold_set,
2836 "underline", &underline,
2837 "underline-set", &underline_set,
2839 "italic-set", &italic_set,
2840 "strikethrough", &strikethrough,
2841 "strikethrough-set", &strikethrough_set,
2843 "color-set", &color_set,
2845 "size-set", &font_size_set,
2846 "family", &font_name,
2847 "family-set", &font_set,
2848 "position", &position,
2849 "position-set", &position_set,
2854 if (response == GTK_RESPONSE_OK) {
2855 memset(&fmt, 0, sizeof(fmt));
2861 fmt.italic = italic;
2862 fmt.cs.italic = TRUE;
2864 if (underline_set) {
2865 fmt.underline = underline;
2866 fmt.cs.underline = TRUE;
2868 if (strikethrough_set) {
2869 fmt.strikethrough = strikethrough;
2870 fmt.cs.strikethrough = TRUE;
2875 ? TEXT_POSITION_NORMAL
2876 : ( ( position == 1 )
2877 ? TEXT_POSITION_SUPERSCRIPT
2878 : TEXT_POSITION_SUBSCRIPT );
2879 fmt.cs.text_position = TRUE;
2880 fmt.font_size = oldfmt.font_size;
2884 fmt.cs.color = TRUE;
2887 fmt.font = wp_get_font_index(font_name,
2892 if (font_size_set) {
2893 fmt.cs.font_size = TRUE;
2894 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
2896 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2897 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2899 gtk_widget_destroy (dialog);
2901 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2905 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2907 ModestMsgEditWindowPrivate *priv;
2909 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2910 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2912 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2914 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2915 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2919 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2921 ModestMsgEditWindowPrivate *priv;
2923 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2924 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2926 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2928 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2929 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2934 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2936 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2938 priv->can_undo = can_undo;
2942 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2944 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2946 priv->can_redo = can_redo;
2950 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
2952 ModestMsgEditWindowPrivate *priv;
2953 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2954 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2956 return priv->can_undo;
2960 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
2962 ModestMsgEditWindowPrivate *priv;
2963 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2964 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2966 return priv->can_redo;
2971 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2974 GtkTextIter match_start, match_end;
2976 if (image_id == NULL)
2979 gtk_text_buffer_get_start_iter (buffer, &iter);
2981 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2982 GSList *tags = gtk_text_iter_get_tags (&match_start);
2984 for (node = tags; node != NULL; node = g_slist_next (node)) {
2985 GtkTextTag *tag = (GtkTextTag *) node->data;
2986 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2987 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2988 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2990 offset = gtk_text_iter_get_offset (&match_start);
2991 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2992 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2996 gtk_text_iter_forward_char (&iter);
3001 message_is_empty (ModestMsgEditWindow *window)
3003 ModestMsgEditWindowPrivate *priv = NULL;
3005 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3006 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3008 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
3009 * so we can ignore markup.
3011 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
3014 count = gtk_text_buffer_get_char_count (buf);
3020 msg_body_focus (GtkWidget *focus,
3021 GdkEventFocus *event,
3025 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3026 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3027 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3032 recpt_field_changed (GtkTextBuffer *buffer,
3033 ModestMsgEditWindow *editor)
3035 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3036 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3040 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3042 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3043 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3047 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3050 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3051 GtkTextBuffer *buffer;
3053 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3054 gtk_text_buffer_set_modified (buffer, modified);
3055 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3056 gtk_text_buffer_set_modified (buffer, modified);
3057 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3058 gtk_text_buffer_set_modified (buffer, modified);
3059 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3063 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3065 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3066 const char *account_name;
3067 GtkTextBuffer *buffer;
3069 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3070 if (gtk_text_buffer_get_modified (buffer))
3072 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3073 if (gtk_text_buffer_get_modified (buffer))
3075 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3076 if (gtk_text_buffer_get_modified (buffer))
3078 if (gtk_text_buffer_get_modified (priv->text_buffer))
3080 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3081 if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3092 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3094 ModestMsgEditWindowPrivate *priv = NULL;
3096 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3097 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3099 /* check if there's no recipient added */
3100 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3101 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3102 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3103 /* no recipient contents, then select contacts */
3104 modest_msg_edit_window_open_addressbook (window, NULL);
3108 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3109 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3112 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3113 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3116 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3117 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3121 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3122 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3123 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3130 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3131 ModestMsgEditWindow *window)
3133 modest_msg_edit_window_offer_attach_file (window);
3137 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3139 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3141 return priv->clipboard_text;
3145 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3147 ModestMsgEditWindow *window)
3149 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3150 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3152 if (!GTK_WIDGET_VISIBLE (window))
3155 g_object_ref (window);
3156 text = gtk_clipboard_wait_for_text (selection_clipboard);
3158 if (priv->clipboard_text != NULL) {
3159 g_free (priv->clipboard_text);
3161 priv->clipboard_text = text;
3163 if (GTK_WIDGET_VISIBLE (window)) {
3164 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3166 g_object_unref (window);
3169 static gboolean clipboard_owner_change_idle (gpointer userdata)
3171 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
3172 ModestMsgEditWindowPrivate *priv;
3174 gdk_threads_enter ();
3175 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3176 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3178 priv->clipboard_owner_idle = 0;
3179 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, window);
3180 gdk_threads_leave ();
3186 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window)
3188 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3189 if (priv->clipboard_owner_idle == 0) {
3190 priv->clipboard_owner_idle = g_idle_add (clipboard_owner_change_idle, window);
3195 subject_field_move_cursor (GtkEntry *entry,
3196 GtkMovementStep step,
3201 if (!GTK_WIDGET_VISIBLE (window))
3204 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3208 update_window_title (ModestMsgEditWindow *window)
3210 ModestMsgEditWindowPrivate *priv = NULL;
3211 const gchar *subject;
3213 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3214 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3215 if (subject == NULL || subject[0] == '\0')
3216 subject = _("mail_va_new_email");
3218 gtk_window_set_title (GTK_WINDOW (window), subject);
3223 subject_field_changed (GtkEditable *editable,
3224 ModestMsgEditWindow *window)
3226 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3227 update_window_title (window);
3228 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3229 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3230 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3234 subject_field_insert_text (GtkEditable *editable,
3236 gint new_text_length,
3238 ModestMsgEditWindow *window)
3240 GString *result = g_string_new ("");
3242 gint result_len = 0;
3243 const gchar *entry_text = NULL;
3246 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3247 old_length = g_utf8_strlen (entry_text, -1);
3249 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3250 gunichar c = g_utf8_get_char_validated (current, 8);
3251 /* Invalid unichar, stop */
3257 result = g_string_append_unichar (result, c);
3261 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3262 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3265 /* Prevent endless recursion */
3266 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3267 g_signal_emit_by_name (editable, "insert-text",
3268 (gpointer) result->str, (gpointer) result->len,
3269 (gpointer) position, (gpointer) window);
3270 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3274 if (result_len + old_length > 1000) {
3275 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3276 dgettext("hildon-common-strings",
3277 "ckdg_ib_maximum_characters_reached"));
3280 g_string_free (result, TRUE);
3284 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3287 ModestMsgEditWindowPrivate *priv = NULL;
3289 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3290 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3292 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3295 gtk_widget_show_all (priv->find_toolbar);
3296 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3298 gtk_widget_hide_all (priv->find_toolbar);
3299 gtk_widget_grab_focus (priv->msg_body);
3305 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3307 GtkTextIter *match_start,
3308 GtkTextIter *match_end)
3310 GtkTextIter end_iter;
3311 gchar *str_casefold;
3314 gchar *range_casefold;
3317 gboolean result = FALSE;
3324 gtk_text_iter_forward_to_end (&end_iter);
3326 str_casefold = g_utf8_casefold (str, -1);
3327 str_chars_n = strlen (str);
3329 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3330 range_casefold = g_utf8_casefold (range_text, -1);
3331 range_chars_n = strlen (range_casefold);
3333 if (range_chars_n < str_chars_n) {
3334 g_free (str_casefold);
3335 g_free (range_text);
3336 g_free (range_casefold);
3340 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3341 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3342 if (!g_utf8_collate (range_subtext, str_casefold)) {
3343 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3345 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3346 match_start, match_end, NULL);
3347 g_free (found_text);
3349 g_free (range_subtext);
3353 g_free (str_casefold);
3354 g_free (range_text);
3355 g_free (range_casefold);
3362 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3363 ModestMsgEditWindow *window)
3365 gchar *current_search = NULL;
3366 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3368 GtkTextIter selection_start, selection_end;
3369 GtkTextIter match_start, match_end;
3370 gboolean continue_search = FALSE;
3372 if (message_is_empty (window)) {
3373 g_free (priv->last_search);
3374 priv->last_search = NULL;
3375 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3379 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3380 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3381 g_free (current_search);
3382 g_free (priv->last_search);
3383 priv->last_search = NULL;
3384 /* Information banner about empty search */
3385 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
3389 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3390 continue_search = TRUE;
3392 g_free (priv->last_search);
3393 priv->last_search = g_strdup (current_search);
3396 if (continue_search) {
3397 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3398 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3399 &match_start, &match_end);
3401 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
3403 GtkTextIter buffer_start;
3404 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3405 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3406 &match_start, &match_end);
3408 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
3411 /* Mark as selected the string found in search */
3413 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3414 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3415 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3417 g_free (priv->last_search);
3418 priv->last_search = NULL;
3420 g_free (current_search);
3424 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3425 ModestMsgEditWindow *window)
3427 GtkToggleAction *toggle;
3428 ModestWindowPrivate *parent_priv;
3429 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3431 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
3432 gtk_toggle_action_set_active (toggle, FALSE);
3436 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3438 ModestMsgEditWindowPrivate *priv;
3440 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3445 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3448 ModestMsgEditWindowPrivate *priv;
3450 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3456 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3459 ModestMsgEditWindowPrivate *priv;
3460 TnyHeader *header = NULL;
3462 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3463 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3465 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3466 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3468 if (priv->draft_msg != NULL) {
3469 g_object_unref (priv->draft_msg);
3472 if (draft != NULL) {
3473 g_object_ref (draft);
3474 header = tny_msg_get_header (draft);
3475 if (priv->msg_uid) {
3476 g_free (priv->msg_uid);
3477 priv->msg_uid = NULL;
3479 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3480 if (GTK_WIDGET_REALIZED (window)) {
3481 if (!modest_window_mgr_register_window (mgr, MODEST_WINDOW (window), NULL)) {
3482 gtk_widget_destroy (GTK_WIDGET (window));
3488 priv->draft_msg = draft;
3492 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3493 GtkTextIter *start, GtkTextIter *end,
3496 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3497 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3500 if (tag == NULL) return;
3501 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3502 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3503 replace_with_images (window, priv->images);
3508 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3511 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3513 g_return_if_fail (TNY_IS_MIME_PART (part));
3514 tny_list_prepend (priv->attachments, (GObject *) part);
3515 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3516 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3517 gtk_widget_show_all (priv->attachments_caption);
3518 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3522 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3524 ModestMsgEditWindowPrivate *priv;
3526 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3527 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3529 return priv->msg_uid;
3533 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3534 ModestMsgEditWindowWidgetType widget_type)
3536 ModestMsgEditWindowPrivate *priv;
3538 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3539 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3541 switch (widget_type) {
3542 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3543 return priv->msg_body;
3545 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3546 return priv->to_field;
3548 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3549 return priv->cc_field;
3551 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3552 return priv->bcc_field;
3554 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3555 return priv->subject_field;
3557 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3558 return priv->attachments_view;
3566 remove_tags (WPTextBuffer *buffer)
3568 GtkTextIter start, end;
3570 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3571 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3573 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3577 on_account_removed (TnyAccountStore *account_store,
3578 TnyAccount *account,
3581 /* Do nothing if it's a store account, because we use the
3582 transport to send the messages */
3583 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3584 const gchar *parent_acc = NULL;
3585 const gchar *our_acc = NULL;
3587 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3588 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3589 /* Close this window if I'm showing a message of the removed account */
3590 if (strcmp (parent_acc, our_acc) == 0)
3591 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3596 on_zoom_minus_plus_not_implemented (ModestWindow *window)
3598 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3600 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
3606 set_zoom_do_nothing (ModestWindow *window,
3612 get_zoom_do_nothing (ModestWindow *window)