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 "modest-scroll-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);
174 static void vadj_changed (GtkAdjustment *adj,
175 ModestMsgEditWindow *window);
177 static void DEBUG_BUFFER (WPTextBuffer *buffer)
181 g_message ("BEGIN BUFFER OF SIZE %d", gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (buffer)));
183 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
184 while (!gtk_text_iter_is_end (&iter)) {
185 GString *output = g_string_new ("");
186 GSList *toggled_tags;
189 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
190 g_string_append_printf (output, "%d: CLOSED [ ", gtk_text_iter_get_offset (&iter));
191 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
192 GtkTextTag *tag = (GtkTextTag *) node->data;
194 g_object_get (G_OBJECT (tag), "name", &name, NULL);
195 output = g_string_append (output, name);
196 g_string_append (output, " ");
198 output = g_string_append (output, "] OPENED [ ");
199 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
200 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
201 GtkTextTag *tag = (GtkTextTag *) node->data;
203 g_object_get (G_OBJECT (tag), "name", &name, NULL);
204 output = g_string_append (output, name);
205 g_string_append (output, " ");
207 output = g_string_append (output, "]\n");
208 g_message ("%s", output->str);
209 g_string_free (output, TRUE);
210 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
212 g_message ("END BUFFER");
217 /* static gboolean */
218 /* on_key_pressed (GtkWidget *self, */
219 /* GdkEventKey *event, */
220 /* gpointer user_data); */
222 /* list my signals */
229 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
230 struct _ModestMsgEditWindowPrivate {
233 GtkWidget *header_box;
235 ModestPairList *from_field_protos;
236 GtkWidget *from_field;
237 gchar *original_account_name;
241 GtkWidget *bcc_field;
242 GtkWidget *subject_field;
243 GtkWidget *attachments_view;
244 GtkWidget *priority_icon;
245 GtkWidget *add_attachment_button;
247 GtkWidget *cc_caption;
248 GtkWidget *bcc_caption;
249 gboolean update_caption_visibility;
250 GtkWidget *attachments_caption;
252 GtkTextBuffer *text_buffer;
254 GtkWidget *font_size_toolitem;
255 GtkWidget *font_face_toolitem;
256 GtkWidget *font_color_button;
257 GSList *font_items_group;
258 GtkWidget *font_tool_button_label;
259 GSList *size_items_group;
260 GtkWidget *size_tool_button_label;
262 GtkWidget *find_toolbar;
265 GtkWidget *font_dialog;
268 guint scroll_drag_timeout_id;
272 TnyList *attachments;
277 TnyHeaderFlags priority_flags;
279 gboolean can_undo, can_redo;
280 gulong clipboard_change_handler_id;
281 gulong default_clipboard_change_handler_id;
282 gulong account_removed_handler_id;
283 guint clipboard_owner_idle;
284 gchar *clipboard_text;
293 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
294 MODEST_TYPE_MSG_EDIT_WINDOW, \
295 ModestMsgEditWindowPrivate))
297 static GtkWindowClass *parent_class = NULL;
299 /* uncomment the following if you have defined any signals */
300 /* static guint signals[LAST_SIGNAL] = {0}; */
303 modest_msg_edit_window_get_type (void)
305 static GType my_type = 0;
307 static const GTypeInfo my_info = {
308 sizeof(ModestMsgEditWindowClass),
309 NULL, /* base init */
310 NULL, /* base finalize */
311 (GClassInitFunc) modest_msg_edit_window_class_init,
312 NULL, /* class finalize */
313 NULL, /* class data */
314 sizeof(ModestMsgEditWindow),
316 (GInstanceInitFunc) modest_msg_edit_window_init,
319 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
320 "ModestMsgEditWindow",
328 save_state (ModestWindow *self)
330 modest_widget_memory_save (modest_runtime_get_conf(),
331 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
336 restore_settings (ModestMsgEditWindow *self)
338 ModestConf *conf = NULL;
340 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
342 conf = modest_runtime_get_conf ();
344 /* Dim at start clipboard actions */
345 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
346 gtk_action_set_sensitive (action, FALSE);
347 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
348 gtk_action_set_sensitive (action, FALSE);
349 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
350 gtk_action_set_sensitive (action, FALSE);
352 modest_widget_memory_restore (conf, G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
357 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
359 GObjectClass *gobject_class;
360 ModestWindowClass *modest_window_class;
361 gobject_class = (GObjectClass*) klass;
362 modest_window_class = (ModestWindowClass*) klass;
364 parent_class = g_type_class_peek_parent (klass);
365 gobject_class->finalize = modest_msg_edit_window_finalize;
367 modest_window_class->set_zoom_func = set_zoom_do_nothing;
368 modest_window_class->get_zoom_func = get_zoom_do_nothing;
369 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
370 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
371 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
372 modest_window_class->save_state_func = save_state;
373 modest_window_class->disconnect_signals_func = modest_msg_edit_window_disconnect_signals;
375 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
379 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
381 ModestMsgEditWindowPrivate *priv;
382 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
384 priv->msg_body = NULL;
386 priv->from_field = NULL;
387 priv->to_field = NULL;
388 priv->cc_field = NULL;
389 priv->bcc_field = NULL;
390 priv->subject_field = NULL;
391 priv->attachments = TNY_LIST (tny_simple_list_new ());
392 priv->images = TNY_LIST (tny_simple_list_new ());
393 priv->images_size = 0;
394 priv->images_count = 0;
397 priv->cc_caption = NULL;
398 priv->bcc_caption = NULL;
399 priv->update_caption_visibility = FALSE;
401 priv->priority_flags = 0;
403 priv->find_toolbar = NULL;
404 priv->last_search = NULL;
406 priv->draft_msg = NULL;
407 priv->outbox_msg = NULL;
408 priv->msg_uid = NULL;
410 priv->can_undo = FALSE;
411 priv->can_redo = FALSE;
412 priv->clipboard_change_handler_id = 0;
413 priv->default_clipboard_change_handler_id = 0;
414 priv->account_removed_handler_id = 0;
415 priv->clipboard_owner_idle = 0;
416 priv->clipboard_text = NULL;
419 priv->scroll_drag_timeout_id = 0;
420 priv->last_upper = 0.0;
422 priv->font_dialog = NULL;
424 modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
425 GTK_WINDOW(obj),"applications_email_editor");
427 if (!is_wp_text_buffer_started) {
428 is_wp_text_buffer_started = TRUE;
429 wp_text_buffer_library_init ();
434 hildon_program_add_window (hildon_program_get_instance(),
440 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
442 static ModestPairList*
443 get_transports (void)
445 GSList *transports = NULL;
447 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
448 GSList *accounts = modest_account_mgr_account_names (account_mgr,
449 TRUE /* only enabled accounts. */);
451 GSList *cursor = accounts;
453 gchar *account_name = cursor->data;
454 gchar *from_string = NULL;
456 from_string = modest_account_mgr_get_from_string (account_mgr,
460 if (from_string && account_name) {
461 gchar *name = account_name;
462 ModestPair *pair = modest_pair_new ((gpointer) name,
463 (gpointer) from_string , TRUE);
464 transports = g_slist_prepend (transports, pair);
467 cursor = cursor->next;
469 g_slist_free (accounts); /* only free the accounts, not the elements,
470 * because they are used in the pairlist */
474 static void window_focus (GtkWindow *window,
478 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
482 scroll_drag_timeout (gpointer userdata)
484 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
485 ModestMsgEditWindowPrivate *priv;
487 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
489 correct_scroll_without_drag_check (win, TRUE);
491 priv->scroll_drag_timeout_id = 0;
497 correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused)
499 ModestMsgEditWindowPrivate *priv;
502 GdkRectangle rectangle;
508 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
510 if (only_if_focused && !gtk_widget_is_focus (priv->msg_body))
513 insert = gtk_text_buffer_get_insert (priv->text_buffer);
514 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
516 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
517 vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll));
518 offset = priv->msg_body->allocation.y;
520 new_value = vadj->value;
522 if ((offset + rectangle.y + rectangle.height) >
523 ((gint) (vadj->value +vadj->page_size))) {
524 new_value = (offset + rectangle.y) - vadj->page_size * 0.25;
525 if (new_value > vadj->upper - vadj->page_size)
526 new_value = vadj->upper - vadj->page_size;
527 } else if ((offset + rectangle.y) < ((gint) vadj->value)) {
528 new_value = (offset + rectangle.y - vadj->page_size * 0.75);
529 if (((gint) (new_value + vadj->page_size)) < (offset + rectangle.y + rectangle.height))
530 new_value = offset + rectangle.y + rectangle.height - (gint) vadj->page_size;
533 if (new_value > vadj->value)
534 new_value = vadj->value;
537 if (vadj->value != new_value) {
538 g_signal_emit_by_name (GTK_TEXT_VIEW(priv->msg_body)->layout,
540 vadj->value = new_value;
541 gtk_adjustment_value_changed (vadj);
542 /* invalidate body */
543 window = gtk_widget_get_parent_window (priv->msg_body);
545 gdk_window_invalidate_rect (window, NULL, TRUE);
551 correct_scroll (ModestMsgEditWindow *w)
553 ModestMsgEditWindowPrivate *priv;
555 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
556 if (gtk_grab_get_current () == priv->msg_body) {
557 if (priv->scroll_drag_timeout_id == 0) {
558 priv->scroll_drag_timeout_id = g_timeout_add (500, (GSourceFunc) scroll_drag_timeout,
564 correct_scroll_without_drag_check (w, TRUE);
568 text_buffer_end_user_action (GtkTextBuffer *buffer,
569 ModestMsgEditWindow *userdata)
572 correct_scroll (userdata);
576 text_buffer_mark_set (GtkTextBuffer *buffer,
579 ModestMsgEditWindow *userdata)
581 gtk_text_buffer_begin_user_action (buffer);
582 gtk_text_buffer_end_user_action (buffer);
586 cut_clipboard_check (GtkTextView *text_view,
589 GtkTextBuffer *buffer;
591 buffer = gtk_text_view_get_buffer (text_view);
592 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
593 g_signal_stop_emission_by_name ((gpointer )text_view, "cut-clipboard");
598 copy_clipboard_check (GtkTextView *text_view,
601 GtkTextBuffer *buffer;
603 buffer = gtk_text_view_get_buffer (text_view);
604 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
605 g_signal_stop_emission_by_name ((gpointer )text_view, "copy-clipboard");
610 vadj_changed (GtkAdjustment *adj,
611 ModestMsgEditWindow *window)
613 ModestMsgEditWindowPrivate *priv;
615 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
617 if (priv->last_upper != adj->upper) {
618 priv->last_upper = adj->upper;
619 correct_scroll (window);
624 attachment_deleted (ModestAttachmentsView *attachments_view,
627 modest_msg_edit_window_remove_attachments (MODEST_MSG_EDIT_WINDOW (user_data),
632 connect_signals (ModestMsgEditWindow *obj)
634 ModestMsgEditWindowPrivate *priv;
636 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
638 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
639 G_CALLBACK (text_buffer_refresh_attributes), obj);
640 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
641 G_CALLBACK (text_buffer_can_undo), obj);
642 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
643 G_CALLBACK (text_buffer_can_redo), obj);
644 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
645 G_CALLBACK (body_changed), obj);
646 g_signal_connect (G_OBJECT (priv->text_buffer), "modified-changed",
647 G_CALLBACK (body_changed), obj);
648 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
649 G_CALLBACK (text_buffer_end_user_action), obj);
650 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
651 G_CALLBACK (text_buffer_mark_set), obj);
652 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
653 G_CALLBACK (text_buffer_apply_tag), obj);
654 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
655 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
656 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
657 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
658 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
659 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
661 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
662 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
664 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
665 G_CALLBACK (msg_body_focus), obj);
666 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
667 G_CALLBACK (msg_body_focus), obj);
668 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
669 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
670 "changed", G_CALLBACK (recpt_field_changed), obj);
671 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
672 "changed", G_CALLBACK (recpt_field_changed), obj);
673 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
674 "changed", G_CALLBACK (recpt_field_changed), obj);
675 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
676 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
677 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
679 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
680 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
682 g_signal_connect (G_OBJECT (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll))),
684 G_CALLBACK (vadj_changed),
687 priv->clipboard_change_handler_id =
688 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
689 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
690 priv->default_clipboard_change_handler_id =
691 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
692 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
694 g_signal_connect (G_OBJECT (priv->msg_body), "cut-clipboard", G_CALLBACK (cut_clipboard_check), NULL);
695 g_signal_connect (G_OBJECT (priv->msg_body), "copy-clipboard", G_CALLBACK (copy_clipboard_check), NULL);
696 g_signal_connect (G_OBJECT (priv->attachments_view), "delete", G_CALLBACK (attachment_deleted), obj);
700 init_window (ModestMsgEditWindow *obj)
702 GtkWidget *to_caption, *subject_caption;
703 GtkWidget *main_vbox;
704 ModestMsgEditWindowPrivate *priv;
705 GtkActionGroup *action_group;
706 ModestWindowPrivate *parent_priv;
707 GdkPixbuf *window_icon = NULL;
708 GError *error = NULL;
710 GtkSizeGroup *title_size_group;
711 GtkSizeGroup *value_size_group;
712 GtkWidget *subject_box;
713 GtkWidget *attachment_icon;
714 GtkWidget *window_box;
715 #if (GTK_MINOR_VERSION >= 10)
716 GdkAtom deserialize_type;
719 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
720 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
722 parent_priv->ui_manager = gtk_ui_manager_new();
723 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
724 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
726 /* Add common actions */
727 gtk_action_group_add_actions (action_group,
728 modest_msg_edit_action_entries,
729 G_N_ELEMENTS (modest_msg_edit_action_entries),
731 gtk_action_group_add_toggle_actions (action_group,
732 modest_msg_edit_toggle_action_entries,
733 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
735 gtk_action_group_add_radio_actions (action_group,
736 modest_msg_edit_alignment_radio_action_entries,
737 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
739 G_CALLBACK (modest_ui_actions_on_change_justify),
741 gtk_action_group_add_radio_actions (action_group,
742 modest_msg_edit_priority_action_entries,
743 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
745 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
747 gtk_action_group_add_radio_actions (action_group,
748 modest_msg_edit_file_format_action_entries,
749 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
750 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
751 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
753 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
754 g_object_unref (action_group);
756 /* Load the UI definition */
757 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
760 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
761 g_clear_error (&error);
764 /* Add accelerators */
765 gtk_window_add_accel_group (GTK_WINDOW (obj),
766 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
768 parent_priv->menubar = NULL;
770 title_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
771 value_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
773 /* Note: This ModestPairList* must exist for as long as the picker
774 * that uses it, because the ModestSelectorPicker uses the ID opaquely,
775 * so it can't know how to manage its memory. */
776 priv->from_field = modest_selector_picker_new (MODEST_EDITABLE_SIZE,
777 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
779 modest_maemo_utils_set_hbutton_layout (title_size_group, value_size_group,
780 _("mail_va_from"), priv->from_field);
782 priv->to_field = modest_recpt_editor_new ();
783 priv->cc_field = modest_recpt_editor_new ();
784 priv->bcc_field = modest_recpt_editor_new ();
785 subject_box = gtk_hbox_new (FALSE, 0);
786 priv->priority_icon = gtk_image_new ();
787 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
788 priv->subject_field = hildon_entry_new (MODEST_EDITABLE_SIZE);
789 gtk_entry_set_max_length (GTK_ENTRY (priv->subject_field) ,SUBJECT_MAX_LENGTH);
790 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
791 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
792 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
793 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
794 priv->add_attachment_button = gtk_button_new ();
795 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
796 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
797 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
798 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 0.5);
799 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
800 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
801 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
802 priv->attachments_view = modest_attachments_view_new (NULL);
804 priv->header_box = gtk_vbox_new (FALSE, 0);
806 to_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
807 _("mail_va_to"), priv->to_field);
808 priv->cc_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
809 _("mail_va_cc"), priv->cc_field);
810 priv->bcc_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
811 _("mail_va_hotfix1"), priv->bcc_field);
812 subject_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
813 _("mail_va_subject"), subject_box);
814 priv->attachments_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
815 _("mail_va_attachment"),
816 priv->attachments_view);
817 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), value_size_group); */
818 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), value_size_group); */
819 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), value_size_group); */
820 g_object_unref (title_size_group);
821 g_object_unref (value_size_group);
823 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->from_field, FALSE, FALSE, 0);
824 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
825 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
826 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
827 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
828 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
829 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
832 priv->msg_body = wp_text_view_new ();
833 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
834 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
835 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
836 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
837 #if (GTK_MINOR_VERSION >= 10)
838 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), NULL);
839 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
841 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
842 deserialize_type, TRUE);
844 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
846 priv->find_toolbar = hildon_find_toolbar_new (NULL);
847 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
849 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
851 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
852 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
853 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
854 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->scroll), TRUE);
856 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
858 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
859 priv->frame = gtk_frame_new (NULL);
860 gtk_box_pack_start (GTK_BOX(main_vbox), priv->frame, TRUE, TRUE, 0);
862 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
863 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
864 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
866 window_box = gtk_vbox_new (FALSE, 0);
867 gtk_container_add (GTK_CONTAINER(obj), window_box);
869 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
871 gtk_container_add (GTK_CONTAINER (priv->frame), priv->msg_body);
873 /* Set window icon */
874 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
876 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
877 g_object_unref (window_icon);
882 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
884 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
886 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
887 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
888 priv->clipboard_change_handler_id))
889 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
890 priv->clipboard_change_handler_id);
891 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
892 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
893 priv->default_clipboard_change_handler_id))
894 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
895 priv->default_clipboard_change_handler_id);
897 if (priv->account_removed_handler_id &&
898 g_signal_handler_is_connected (modest_runtime_get_account_store (),
899 priv->account_removed_handler_id))
900 g_signal_handler_disconnect(modest_runtime_get_account_store (),
901 priv->account_removed_handler_id);
905 modest_msg_edit_window_finalize (GObject *obj)
907 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
909 /* Sanity check: shouldn't be needed, the window mgr should
910 call this function before */
911 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
913 if (priv->font_dialog != NULL) {
914 gtk_dialog_response (GTK_DIALOG (priv->font_dialog), GTK_RESPONSE_NONE);
917 if (priv->clipboard_text != NULL) {
918 g_free (priv->clipboard_text);
919 priv->clipboard_text = NULL;
922 if (priv->draft_msg != NULL) {
923 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
924 if (TNY_IS_HEADER (header)) {
925 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
926 modest_window_mgr_unregister_header (mgr, header);
928 g_object_unref (priv->draft_msg);
929 priv->draft_msg = NULL;
931 if (priv->outbox_msg != NULL) {
932 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
933 if (TNY_IS_HEADER (header)) {
934 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
935 modest_window_mgr_unregister_header (mgr, header);
937 g_object_unref (priv->outbox_msg);
938 priv->outbox_msg = NULL;
940 if (priv->scroll_drag_timeout_id > 0) {
941 g_source_remove (priv->scroll_drag_timeout_id);
942 priv->scroll_drag_timeout_id = 0;
944 if (priv->clipboard_owner_idle > 0) {
945 g_source_remove (priv->clipboard_owner_idle);
946 priv->clipboard_owner_idle = 0;
948 if (priv->original_account_name)
949 g_free (priv->original_account_name);
950 g_free (priv->msg_uid);
951 g_free (priv->last_search);
952 g_slist_free (priv->font_items_group);
953 g_slist_free (priv->size_items_group);
954 g_object_unref (priv->attachments);
955 g_object_unref (priv->images);
957 /* This had to stay alive for as long as the picker that used it: */
958 modest_pair_list_free (priv->from_field_protos);
960 G_OBJECT_CLASS(parent_class)->finalize (obj);
964 pixbuf_from_stream (TnyStream *stream, const gchar *mime_type, guint64 *stream_size)
966 GdkPixbufLoader *loader;
972 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
974 if (loader == NULL) {
980 tny_stream_reset (TNY_STREAM (stream));
981 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
982 GError *error = NULL;
983 unsigned char read_buffer[128];
985 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
987 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, &error)) {
989 g_error_free (error);
994 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
996 g_object_ref (pixbuf);
997 gdk_pixbuf_loader_close (loader, NULL);
998 g_object_unref (loader);
1003 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1004 GdkPixbuf *new_pixbuf;
1006 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1007 gdk_pixbuf_get_width (pixbuf);
1008 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1009 g_object_unref (pixbuf);
1010 pixbuf = new_pixbuf;
1014 *stream_size = size;
1020 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1022 ModestMsgEditWindowPrivate *priv;
1025 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1027 for (iter = tny_list_create_iterator (attachments);
1028 !tny_iterator_is_done (iter);
1029 tny_iterator_next (iter)) {
1030 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1031 const gchar *cid = tny_mime_part_get_content_id (part);
1032 const gchar *mime_type = tny_mime_part_get_content_type (part);
1033 if ((cid != NULL)&&(mime_type != NULL)) {
1034 guint64 stream_size;
1035 TnyStream *stream = tny_mime_part_get_decoded_stream (part);
1036 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
1039 g_object_unref (stream);
1041 if (pixbuf != NULL) {
1042 priv->images_count ++;
1043 priv->images_size += stream_size;
1044 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1045 g_object_unref (pixbuf);
1048 g_object_unref (part);
1050 g_object_unref (iter);
1054 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1056 TnyMimePart *parent = NULL;
1057 const gchar *content_type = NULL;
1058 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1060 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1062 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1063 parent = g_object_ref (msg);
1064 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1065 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1068 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1069 iter = tny_list_create_iterator (parts);
1070 while (!tny_iterator_is_done (iter)) {
1072 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1073 content_type = tny_mime_part_get_content_type (part);
1074 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1078 g_object_unref (part);
1080 tny_iterator_next (iter);
1082 g_object_unref (iter);
1083 g_object_unref (parts);
1086 if (parent != NULL) {
1087 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1090 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1091 iter = tny_list_create_iterator (parts);
1092 while (!tny_iterator_is_done (iter)) {
1094 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1095 content_type = tny_mime_part_get_content_type (part);
1096 if (content_type && g_str_has_prefix (content_type, "image/")) {
1097 tny_list_prepend (priv->images, (GObject *) part);
1099 g_object_unref (part);
1100 tny_iterator_next (iter);
1102 g_object_unref (iter);
1103 g_object_unref (parts);
1104 g_object_unref (parent);
1109 update_next_cid (ModestMsgEditWindow *self, TnyList *attachments)
1112 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1114 for (iter = tny_list_create_iterator (attachments) ;
1115 !tny_iterator_is_done (iter);
1116 tny_iterator_next (iter)) {
1117 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1118 const gchar *cid = tny_mime_part_get_content_id (part);
1120 char *invalid = NULL;
1121 gint int_cid = strtol (cid, &invalid, 10);
1122 if ((invalid != NULL) && (*invalid == '\0') && (int_cid >= priv->next_cid)) {
1123 priv->next_cid = int_cid + 1;
1126 g_object_unref (part);
1128 g_object_unref (iter);
1132 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1135 gchar *to, *cc, *bcc, *subject;
1137 ModestMsgEditWindowPrivate *priv;
1139 TnyHeaderFlags priority_flags;
1140 TnyFolder *msg_folder;
1141 gboolean is_html = FALSE;
1143 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1144 g_return_if_fail (TNY_IS_MSG (msg));
1146 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1148 header = tny_msg_get_header (msg);
1149 to = tny_header_dup_to (header);
1150 cc = tny_header_dup_cc (header);
1151 bcc = tny_header_dup_bcc (header);
1152 subject = tny_header_dup_subject (header);
1153 priority_flags = tny_header_get_priority (header);
1156 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1158 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1159 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1160 gtk_widget_show (priv->cc_caption);
1161 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1162 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1163 gtk_widget_hide (priv->cc_caption);
1166 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1167 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1168 gtk_widget_show (priv->bcc_caption);
1169 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1170 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1171 gtk_widget_hide (priv->bcc_caption);
1174 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1175 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1178 update_window_title (self);
1180 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1181 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1183 if ((body == NULL)||(body[0] == '\0')) {
1185 body = modest_text_utils_convert_to_html ("");
1188 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1189 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1192 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1195 /* Add attachments to the view */
1196 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1197 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1198 if (tny_list_get_length (priv->attachments) == 0) {
1199 gtk_widget_hide (priv->attachments_caption);
1201 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1202 gtk_widget_show_all (priv->attachments_caption);
1204 get_related_images (self, msg);
1205 update_next_cid (self, priv->attachments);
1206 update_next_cid (self, priv->images);
1207 replace_with_images (self, priv->images);
1209 if (preserve_is_rich && !is_html) {
1210 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1211 /* Get the default format required from configuration */
1212 } else if (!preserve_is_rich && !modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1213 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1216 /* Set the default focus depending on having already a To: field or not */
1217 if ((!to)||(*to == '\0')) {
1218 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1220 gtk_widget_grab_focus (priv->msg_body);
1223 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1225 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1226 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1228 modest_msg_edit_window_set_modified (self, FALSE);
1230 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1231 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1232 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1233 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1235 if (priv->msg_uid) {
1236 g_free (priv->msg_uid);
1237 priv->msg_uid = NULL;
1240 /* we should set a reference to the incoming message if it is a draft */
1241 msg_folder = tny_msg_get_folder (msg);
1243 if (modest_tny_folder_is_local_folder (msg_folder)) {
1244 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1245 if (type == TNY_FOLDER_TYPE_INVALID)
1246 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1248 if (type == TNY_FOLDER_TYPE_DRAFTS)
1249 priv->draft_msg = g_object_ref(msg);
1250 if (type == TNY_FOLDER_TYPE_OUTBOX)
1251 priv->outbox_msg = g_object_ref(msg);
1252 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1254 g_object_unref (msg_folder);
1264 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
1267 GList *item_children, *node;
1268 GtkWidget *bin_child;
1270 bin_child = gtk_bin_get_child (GTK_BIN(item));
1272 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
1274 for (node = item_children; node != NULL; node = g_list_next (node)) {
1275 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
1276 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
1279 g_list_free (item_children);
1283 menu_tool_button_dont_expand (GtkMenuToolButton *item)
1286 GList *item_children, *node;
1288 box = gtk_bin_get_child (GTK_BIN (item));
1289 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
1290 item_children = gtk_container_get_children (GTK_CONTAINER (box));
1292 for (node = item_children; node != NULL; node = g_list_next (node)) {
1293 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
1294 if (GTK_IS_TOGGLE_BUTTON (node->data))
1295 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
1296 else if (GTK_IS_BUTTON (node->data))
1297 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
1299 g_list_free (item_children);
1304 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1306 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1307 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1308 GtkWidget *placeholder;
1309 GtkWidget *tool_item;
1314 GtkWidget *sizes_menu;
1315 GtkWidget *fonts_menu;
1316 GSList *radio_group = NULL;
1317 GSList *node = NULL;
1321 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1322 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1324 /* Font color placeholder */
1325 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1326 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1329 tool_item = GTK_WIDGET (gtk_tool_item_new ());
1330 priv->font_color_button = hildon_color_button_new ();
1331 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
1332 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1333 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
1334 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1335 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1336 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1337 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1339 G_CALLBACK (modest_msg_edit_window_color_button_change),
1342 /* Font size and face placeholder */
1343 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1344 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1346 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1347 priv->size_tool_button_label = gtk_label_new (NULL);
1348 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1349 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1350 size_text,"</span>", NULL);
1351 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1353 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
1354 sizes_menu = gtk_menu_new ();
1355 priv->size_items_group = NULL;
1357 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1358 GtkWidget *size_menu_item;
1360 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1361 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
1362 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
1363 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
1364 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
1365 gtk_widget_show (size_menu_item);
1367 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
1371 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1372 GtkWidget *item = (GtkWidget *) node->data;
1373 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
1377 priv->size_items_group = g_slist_reverse (priv->size_items_group);
1378 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
1379 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1380 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1381 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1382 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1383 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1384 priv->font_size_toolitem = tool_item;
1387 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1388 priv->font_tool_button_label = gtk_label_new (NULL);
1389 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1390 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1392 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
1393 fonts_menu = gtk_menu_new ();
1394 priv->font_items_group = NULL;
1396 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1397 GtkWidget *font_menu_item;
1398 GtkWidget *child_label;
1400 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
1401 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
1402 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
1403 wp_get_font_name (font_index), "</span>", NULL);
1404 gtk_label_set_markup (GTK_LABEL (child_label), markup);
1407 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
1408 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
1409 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
1410 gtk_widget_show (font_menu_item);
1412 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
1415 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1416 GtkWidget *item = (GtkWidget *) node->data;
1417 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
1420 priv->font_items_group = g_slist_reverse (priv->font_items_group);
1421 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
1422 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1423 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1424 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1425 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1426 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1427 priv->font_face_toolitem = tool_item;
1429 /* Set expand and homogeneous for remaining items */
1430 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1431 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1432 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1433 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1434 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1435 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1436 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1437 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1438 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1440 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1441 will not show the tool items added to the placeholders) */
1442 gtk_widget_show_all (parent_priv->toolbar);
1444 /* Set the no show all *after* showing all items. We do not
1445 want the toolbar to be shown with a show all because it
1446 could go agains the gconf setting regarding showing or not
1447 the toolbar of the editor window */
1448 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1454 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean preserve_is_rich)
1457 ModestWindowPrivate *parent_priv;
1458 ModestMsgEditWindowPrivate *priv;
1459 ModestDimmingRulesGroup *menu_rules_group = NULL;
1460 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1461 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1462 ModestWindowMgr *mgr = NULL;
1464 g_return_val_if_fail (msg, NULL);
1465 g_return_val_if_fail (account_name, NULL);
1467 mgr = modest_runtime_get_window_mgr ();
1469 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1471 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1472 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1474 /* Menubar. Update the state of some toggles */
1475 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1476 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
1477 priv->from_field_protos = get_transports ();
1478 modest_selector_picker_set_pair_list (MODEST_SELECTOR_PICKER (priv->from_field), priv->from_field_protos);
1479 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1480 hildon_button_set_title (HILDON_BUTTON (priv->from_field),
1482 hildon_button_set_value (HILDON_BUTTON (priv->from_field),
1483 hildon_touch_selector_get_current_text
1484 (HILDON_TOUCH_SELECTOR (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (priv->from_field)))));
1485 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1486 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1489 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1491 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1493 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1495 priv->original_account_name = (account_name) ? g_strdup (account_name) : NULL;
1497 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new ();
1498 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1499 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1500 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1501 /* Add common dimming rules */
1502 modest_dimming_rules_group_add_rules (menu_rules_group,
1503 modest_msg_edit_window_menu_dimming_entries,
1504 G_N_ELEMENTS (modest_msg_edit_window_menu_dimming_entries),
1505 MODEST_WINDOW (obj));
1506 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1507 modest_msg_edit_window_toolbar_dimming_entries,
1508 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1509 MODEST_WINDOW (obj));
1510 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_button,
1511 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1512 MODEST_WINDOW (obj));
1513 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1514 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1515 MODEST_WINDOW (obj));
1516 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1517 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1518 MODEST_WINDOW (obj));
1519 /* Insert dimming rules group for this window */
1520 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1521 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1522 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1523 /* Checks the dimming rules */
1524 g_object_unref (menu_rules_group);
1525 g_object_unref (toolbar_rules_group);
1526 g_object_unref (clipboard_rules_group);
1527 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1529 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1531 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1532 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1533 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1534 priv->update_caption_visibility = TRUE;
1536 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1538 /* Track account-removed signal, this window should be closed
1539 in the case we're creating a mail associated to the account
1541 priv->account_removed_handler_id =
1542 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1544 G_CALLBACK(on_account_removed),
1547 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (MODEST_MSG_EDIT_WINDOW (obj));
1549 return (ModestWindow*) obj;
1553 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1555 GString **string_buffer = (GString **) user_data;
1557 *string_buffer = g_string_append (*string_buffer, buffer);
1563 * @result: A new string which should be freed with g_free().
1566 get_formatted_data (ModestMsgEditWindow *edit_window)
1568 ModestMsgEditWindowPrivate *priv;
1569 GString *string_buffer = g_string_new ("");
1571 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1573 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1575 modest_text_utils_hyperlinkify (string_buffer);
1577 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1579 return g_string_free (string_buffer, FALSE);
1584 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1587 const gchar *account_name;
1588 ModestMsgEditWindowPrivate *priv;
1589 TnyIterator *att_iter;
1591 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1593 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1595 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1596 g_return_val_if_fail (account_name, NULL);
1599 /* don't free these (except from) */
1600 data = g_slice_new0 (MsgData);
1601 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1603 data->account_name = g_strdup (account_name);
1604 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1605 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1606 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1607 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1608 if (priv->draft_msg) {
1609 data->draft_msg = g_object_ref (priv->draft_msg);
1610 } else if (priv->outbox_msg) {
1611 data->draft_msg = g_object_ref (priv->outbox_msg);
1613 data->draft_msg = NULL;
1616 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1618 gtk_text_buffer_get_bounds (buf, &b, &e);
1619 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1621 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1622 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1624 data->html_body = NULL;
1626 /* deep-copy the data */
1627 att_iter = tny_list_create_iterator (priv->attachments);
1628 data->attachments = NULL;
1629 while (!tny_iterator_is_done (att_iter)) {
1630 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1631 if (!(TNY_IS_MIME_PART(part))) {
1632 g_warning ("strange data in attachment list");
1633 g_object_unref (part);
1634 tny_iterator_next (att_iter);
1637 data->attachments = g_list_append (data->attachments,
1639 tny_iterator_next (att_iter);
1641 g_object_unref (att_iter);
1643 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1644 att_iter = tny_list_create_iterator (priv->images);
1645 data->images = NULL;
1646 while (!tny_iterator_is_done (att_iter)) {
1647 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1649 if (!(TNY_IS_MIME_PART(part))) {
1650 g_warning ("strange data in attachment list");
1651 g_object_unref (part);
1652 tny_iterator_next (att_iter);
1655 cid = tny_mime_part_get_content_id (part);
1657 gchar *image_tag_id;
1658 GtkTextTag *image_tag;
1660 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1661 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1662 g_free (image_tag_id);
1664 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1666 ((gtk_text_iter_has_tag (&iter, image_tag))||
1667 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1668 data->images = g_list_append (data->images,
1669 g_object_ref (part));
1671 g_object_unref (part);
1672 tny_iterator_next (att_iter);
1674 g_object_unref (att_iter);
1676 data->priority_flags = priv->priority_flags;
1683 unref_gobject (GObject *obj, gpointer data)
1685 if (!G_IS_OBJECT(obj))
1687 g_object_unref (obj);
1691 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1694 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1702 g_free (data->from);
1703 g_free (data->subject);
1704 g_free (data->plain_body);
1705 g_free (data->html_body);
1706 g_free (data->account_name);
1708 if (data->draft_msg != NULL) {
1709 g_object_unref (data->draft_msg);
1710 data->draft_msg = NULL;
1713 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1714 g_list_free (data->attachments);
1715 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1716 g_list_free (data->images);
1718 g_slice_free (MsgData, data);
1722 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1724 guint64 *parts_size)
1726 ModestMsgEditWindowPrivate *priv;
1728 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1730 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1732 /* TODO: add images */
1733 *parts_size += priv->images_size;
1734 *parts_count += priv->images_count;
1739 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1742 ModestMsgEditWindowPrivate *priv = NULL;
1743 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1745 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1747 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1749 return MODEST_MSG_EDIT_FORMAT_HTML;
1751 return MODEST_MSG_EDIT_FORMAT_TEXT;
1755 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1756 ModestMsgEditFormat format)
1758 ModestMsgEditWindowPrivate *priv;
1760 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1761 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1764 case MODEST_MSG_EDIT_FORMAT_HTML:
1765 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1767 case MODEST_MSG_EDIT_FORMAT_TEXT:
1768 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1771 g_return_if_reached ();
1775 ModestMsgEditFormatState *
1776 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1778 ModestMsgEditFormatState *format_state = NULL;
1779 ModestMsgEditWindowPrivate *priv;
1780 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1782 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1783 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1785 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1787 format_state = g_new0 (ModestMsgEditFormatState, 1);
1788 format_state->bold = buffer_format->bold&0x1;
1789 format_state->italics = buffer_format->italic&0x1;
1790 format_state->bullet = buffer_format->bullet&0x1;
1791 format_state->color = buffer_format->color;
1792 format_state->font_size = buffer_format->font_size;
1793 format_state->font_family = wp_get_font_name (buffer_format->font);
1794 format_state->justification = buffer_format->justification;
1795 g_free (buffer_format);
1797 return format_state;
1802 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1803 const ModestMsgEditFormatState *format_state)
1805 ModestMsgEditWindowPrivate *priv;
1806 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1807 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1808 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1809 g_return_if_fail (format_state != NULL);
1811 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1812 gtk_widget_grab_focus (priv->msg_body);
1813 buffer_format->bold = (format_state->bold != FALSE);
1814 buffer_format->italic = (format_state->italics != FALSE);
1815 buffer_format->color = format_state->color;
1816 buffer_format->font_size = format_state->font_size;
1817 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1818 buffer_format->justification = format_state->justification;
1819 buffer_format->bullet = format_state->bullet;
1821 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1823 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1824 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1825 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1826 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1827 buffer_format->cs.font = (buffer_format->font != current_format->font);
1828 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1829 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1831 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1832 if (buffer_format->cs.bold) {
1833 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1834 GINT_TO_POINTER (buffer_format->bold&0x1));
1836 if (buffer_format->cs.italic) {
1837 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1838 GINT_TO_POINTER (buffer_format->italic&0x1));
1840 if (buffer_format->cs.color) {
1841 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1842 GINT_TO_POINTER (&(buffer_format->color)));
1844 if (buffer_format->cs.font_size) {
1845 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1846 GINT_TO_POINTER (buffer_format->font_size));
1848 if (buffer_format->cs.justification) {
1849 switch (buffer_format->justification) {
1850 case GTK_JUSTIFY_LEFT:
1851 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1852 GINT_TO_POINTER(TRUE));
1854 case GTK_JUSTIFY_CENTER:
1855 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1856 GINT_TO_POINTER(TRUE));
1858 case GTK_JUSTIFY_RIGHT:
1859 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1860 GINT_TO_POINTER(TRUE));
1867 if (buffer_format->cs.font) {
1868 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1869 GINT_TO_POINTER (buffer_format->font));
1871 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1872 if (buffer_format->cs.bullet) {
1873 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
1874 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
1876 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1878 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
1880 g_free (buffer_format);
1881 g_free (current_format);
1883 /* Check dimming rules */
1884 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1885 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1889 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1891 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1893 ModestWindowPrivate *parent_priv;
1894 ModestMsgEditWindowPrivate *priv;
1895 GtkWidget *new_size_menuitem;
1896 GtkWidget *new_font_menuitem;
1898 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1899 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1901 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1902 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu");
1903 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1904 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1906 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatPlainTextMenu");
1907 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1908 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1911 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1913 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1914 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1916 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1917 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1919 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
1920 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
1923 switch (buffer_format->justification)
1925 case GTK_JUSTIFY_LEFT:
1926 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1928 case GTK_JUSTIFY_CENTER:
1929 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1931 case GTK_JUSTIFY_RIGHT:
1932 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1939 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1941 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1942 G_CALLBACK (modest_msg_edit_window_color_button_change),
1944 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1945 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1946 G_CALLBACK (modest_msg_edit_window_color_button_change),
1949 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1950 buffer_format->font_size))->data);
1951 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1955 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1956 markup = g_strconcat ("<span font_family='Sans'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1957 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1959 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1960 G_CALLBACK (modest_msg_edit_window_size_change),
1962 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1963 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1964 G_CALLBACK (modest_msg_edit_window_size_change),
1968 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1969 buffer_format->font))->data);
1970 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1974 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1975 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1976 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1978 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1979 G_CALLBACK (modest_msg_edit_window_font_change),
1981 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1982 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1983 G_CALLBACK (modest_msg_edit_window_font_change),
1987 g_free (buffer_format);
1991 #ifdef MODEST_HILDON_VERSION_0
1993 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1996 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1997 ModestMsgEditWindowPrivate *priv;
1998 GtkWidget *dialog = NULL;
2000 GdkColor *new_color = NULL;
2002 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2003 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2005 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2006 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2007 g_free (buffer_format);
2009 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2010 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2011 if (new_color != NULL) {
2012 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2013 (gpointer) new_color);
2016 gtk_widget_destroy (dialog);
2021 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2024 ModestMsgEditWindowPrivate *priv;
2025 GtkWidget *dialog = NULL;
2027 GdkColor *old_color = NULL;
2028 const GdkColor *new_color = NULL;
2030 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2031 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2033 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2034 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2036 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2037 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2038 if (new_color != NULL)
2039 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2041 gtk_widget_destroy (dialog);
2047 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2050 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2051 ModestMsgEditWindowPrivate *priv;
2052 GtkWidget *dialog = NULL;
2054 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2055 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2057 dialog = hildon_color_chooser_new ();
2058 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2059 g_free (buffer_format);
2061 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2063 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2064 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2067 gtk_widget_destroy (dialog);
2072 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2075 ModestMsgEditWindowPrivate *priv;
2076 GtkWidget *dialog = NULL;
2077 GdkColor *old_color = NULL;
2079 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2080 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2082 dialog = hildon_color_chooser_new ();
2083 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2085 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2087 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2088 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2090 gtk_widget_destroy (dialog);
2093 #endif /*!MODEST_HILDON_VERSION_0*/
2098 create_stream_for_uri (const gchar* uri)
2103 TnyStream *result = NULL;
2105 GnomeVFSHandle *handle = NULL;
2106 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2107 if (test == GNOME_VFS_OK) {
2108 TnyStream *vfssstream = TNY_STREAM (tny_vfs_stream_new (handle));
2109 /* Streams over OBEX (Bluetooth) are not seekable but
2110 * we expect them to be (we might need to read them
2111 * several times). So if this is a Bluetooth URI just
2112 * read the whole file into memory (this is not a fast
2113 * protocol so we can assume that these files are not
2114 * going to be very big) */
2115 if ((g_ascii_strncasecmp (uri, "obex://", 7) == 0)||
2116 (g_ascii_strncasecmp (uri, "upnpav://", 9) == 0)) {
2117 TnyStream *memstream = tny_camel_mem_stream_new ();
2118 tny_stream_write_to_stream (vfssstream, memstream);
2119 g_object_unref (vfssstream);
2122 result = vfssstream;
2130 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2133 ModestMsgEditWindowPrivate *priv;
2134 GtkWidget *dialog = NULL;
2136 GSList *uris = NULL;
2137 GSList *uri_node = NULL;
2139 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2141 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2142 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2143 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2145 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2147 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2148 GTK_WINDOW (dialog), GTK_WINDOW (window));
2150 response = gtk_dialog_run (GTK_DIALOG (dialog));
2152 case GTK_RESPONSE_OK:
2153 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2158 gtk_widget_destroy (dialog);
2160 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2162 GnomeVFSHandle *handle = NULL;
2163 GnomeVFSResult result;
2164 GtkTextIter position;
2165 GtkTextMark *insert_mark;
2167 uri = (const gchar *) uri_node->data;
2168 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2169 if (result == GNOME_VFS_OK) {
2171 GnomeVFSFileInfo *info;
2172 gchar *filename, *basename, *escaped_filename;
2173 TnyMimePart *mime_part;
2175 const gchar *mime_type = NULL;
2176 GnomeVFSURI *vfs_uri;
2177 guint64 stream_size;
2179 gnome_vfs_close (handle);
2180 vfs_uri = gnome_vfs_uri_new (uri);
2182 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2183 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2184 g_free (escaped_filename);
2185 gnome_vfs_uri_unref (vfs_uri);
2186 info = gnome_vfs_file_info_new ();
2188 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2189 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2191 mime_type = gnome_vfs_file_info_get_mime_type (info);
2193 mime_part = tny_platform_factory_new_mime_part
2194 (modest_runtime_get_platform_factory ());
2196 TnyStream *stream = create_stream_for_uri (uri);
2198 if (stream == NULL) {
2200 modest_platform_information_banner (NULL, NULL, dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2202 g_object_unref (mime_part);
2203 gnome_vfs_file_info_unref (info);
2207 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2209 content_id = g_strdup_printf ("%d", priv->next_cid);
2210 tny_mime_part_set_content_id (mime_part, content_id);
2211 g_free (content_id);
2214 basename = g_path_get_basename (filename);
2215 tny_mime_part_set_filename (mime_part, basename);
2218 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
2220 if (pixbuf != NULL) {
2221 priv->images_size += stream_size;
2222 priv->images_count ++;
2223 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2224 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2225 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
2226 g_object_unref (pixbuf);
2229 tny_list_prepend (priv->images, (GObject *) mime_part);
2230 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2232 g_object_unref (mime_part);
2233 gnome_vfs_file_info_unref (info);
2242 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2244 GtkWidget *dialog = NULL;
2246 GSList *uris = NULL;
2248 GnomeVFSFileSize total_size, allowed_size;
2249 ModestMsgEditWindowPrivate *priv;
2253 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(window));
2255 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2257 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2260 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2261 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2262 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2263 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), GTK_WINDOW (window));
2265 response = gtk_dialog_run (GTK_DIALOG (dialog));
2267 case GTK_RESPONSE_OK:
2268 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2273 gtk_widget_destroy (dialog);
2275 /* allowed size is the maximum size - what's already there */
2276 modest_attachments_view_get_sizes (
2277 MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2278 &att_num, &att_size);
2279 allowed_size = MODEST_MAX_ATTACHMENT_SIZE - att_size;
2282 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2284 const gchar *uri = (const gchar *) uri_node->data;
2286 total_size += modest_msg_edit_window_attach_file_one
2287 (window, uri, allowed_size);
2289 if (total_size > allowed_size) {
2290 g_warning ("%s: total size: %u",
2291 __FUNCTION__, (unsigned int)total_size);
2295 allowed_size -= total_size;
2299 g_slist_foreach (uris, (GFunc) g_free, NULL);
2300 g_slist_free (uris);
2305 modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window,
2307 GnomeVFSFileSize allowed_size)
2310 GnomeVFSHandle *handle = NULL;
2311 ModestMsgEditWindowPrivate *priv;
2312 GnomeVFSResult result;
2313 GnomeVFSFileSize size = 0;
2314 g_return_val_if_fail (window, 0);
2315 g_return_val_if_fail (uri, 0);
2317 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2319 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2320 if (result == GNOME_VFS_OK) {
2321 TnyMimePart *mime_part;
2323 const gchar *mime_type = NULL;
2325 gchar *escaped_filename;
2328 GnomeVFSFileInfo *info;
2329 GnomeVFSURI *vfs_uri;
2331 gnome_vfs_close (handle);
2332 vfs_uri = gnome_vfs_uri_new (uri);
2335 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2336 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2337 g_free (escaped_filename);
2338 gnome_vfs_uri_unref (vfs_uri);
2340 info = gnome_vfs_file_info_new ();
2342 if (gnome_vfs_get_file_info (uri,
2344 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2346 mime_type = gnome_vfs_file_info_get_mime_type (info);
2347 mime_part = tny_platform_factory_new_mime_part
2348 (modest_runtime_get_platform_factory ());
2350 /* try to get the attachment's size; this may fail for weird
2351 * file systems, like obex, upnp... */
2352 if (allowed_size != 0 &&
2353 info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
2355 if (size > allowed_size) {
2356 modest_platform_information_banner (NULL, NULL,
2357 dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2361 g_warning ("%s: could not get attachment size", __FUNCTION__);
2363 stream = create_stream_for_uri (uri);
2365 if (stream == NULL) {
2367 modest_platform_information_banner (NULL, NULL, dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2369 g_object_unref (mime_part);
2370 gnome_vfs_file_info_unref (info);
2374 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2375 g_object_unref (stream);
2377 content_id = g_strdup_printf ("%d", priv->next_cid);
2378 tny_mime_part_set_content_id (mime_part, content_id);
2379 g_free (content_id);
2382 basename = g_path_get_basename (filename);
2383 tny_mime_part_set_filename (mime_part, basename);
2386 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2387 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2389 info->size == 0, info->size);
2390 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2391 gtk_widget_show_all (priv->attachments_caption);
2392 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2394 g_object_unref (mime_part);
2395 gnome_vfs_file_info_unref (info);
2402 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2405 ModestMsgEditWindowPrivate *priv;
2408 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2409 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2411 if (att_list == NULL) {
2412 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2414 g_object_ref (att_list);
2417 if (tny_list_get_length (att_list) == 0) {
2418 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2420 gboolean dialog_response;
2421 gchar *message = NULL;
2422 gchar *filename = NULL;
2424 if (tny_list_get_length (att_list) == 1) {
2426 iter = tny_list_create_iterator (att_list);
2427 part = (TnyMimePart *) tny_iterator_get_current (iter);
2428 g_object_unref (iter);
2429 if (TNY_IS_MSG (part)) {
2430 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2432 filename = tny_header_dup_subject (header);
2433 g_object_unref (header);
2435 if (filename == NULL) {
2436 filename = g_strdup (_("mail_va_no_subject"));
2439 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2441 g_object_unref (part);
2443 filename = g_strdup ("");
2445 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
2446 tny_list_get_length (att_list)), filename);
2449 dialog_response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window), message);
2452 if (dialog_response != GTK_RESPONSE_OK) {
2453 g_object_unref (att_list);
2456 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
2458 for (iter = tny_list_create_iterator (att_list);
2459 !tny_iterator_is_done (iter);
2460 tny_iterator_next (iter)) {
2461 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2462 const gchar *att_id;
2463 tny_list_remove (priv->attachments, (GObject *) mime_part);
2465 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2467 if (tny_list_get_length (priv->attachments) == 0)
2468 gtk_widget_hide (priv->attachments_caption);
2469 att_id = tny_mime_part_get_content_id (mime_part);
2471 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2473 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2474 g_object_unref (mime_part);
2476 g_object_unref (iter);
2479 g_object_unref (att_list);
2481 /* if the last attachment has been removed, focus the Subject: field */
2482 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2483 gtk_widget_grab_focus (priv->subject_field);
2487 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2490 ModestMsgEditWindowPrivate *priv;
2491 GdkColor *new_color;
2492 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2494 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2495 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2498 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2500 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2502 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2504 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2509 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
2512 ModestMsgEditWindowPrivate *priv;
2513 gint new_size_index;
2514 ModestMsgEditWindow *window;
2517 window = MODEST_MSG_EDIT_WINDOW (userdata);
2518 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2519 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2521 if (gtk_check_menu_item_get_active (menu_item)) {
2523 WPTextBufferFormat format;
2525 memset (&format, 0, sizeof (format));
2526 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2528 label = gtk_bin_get_child (GTK_BIN (menu_item));
2530 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
2531 format.cs.font_size = TRUE;
2532 format.cs.text_position = TRUE;
2533 format.cs.font = TRUE;
2534 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
2535 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2537 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2538 GINT_TO_POINTER (wp_get_font_size_index (new_size_index, 12))))
2539 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2541 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2542 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
2543 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2549 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
2552 ModestMsgEditWindowPrivate *priv;
2553 gint new_font_index;
2554 ModestMsgEditWindow *window;
2557 window = MODEST_MSG_EDIT_WINDOW (userdata);
2558 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2559 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2561 if (gtk_check_menu_item_get_active (menu_item)) {
2564 label = gtk_bin_get_child (GTK_BIN (menu_item));
2566 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
2568 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2569 GINT_TO_POINTER(new_font_index)))
2570 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2572 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2573 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2574 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2580 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2583 ModestMsgEditWindowPrivate *priv = NULL;
2584 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2586 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2587 if (!priv->update_caption_visibility)
2590 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2592 gtk_widget_show (priv->cc_caption);
2594 gtk_widget_hide (priv->cc_caption);
2596 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2600 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2603 ModestMsgEditWindowPrivate *priv = NULL;
2604 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2606 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2607 if (!priv->update_caption_visibility)
2610 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2612 gtk_widget_show (priv->bcc_caption);
2614 gtk_widget_hide (priv->bcc_caption);
2616 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2620 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2621 ModestRecptEditor *editor)
2623 ModestMsgEditWindowPrivate *priv;
2625 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2626 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2628 /* we check for low-mem; in that case, show a warning, and don't allow
2629 * for the addressbook
2631 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2634 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2636 if (editor == NULL) {
2637 GtkWidget *view_focus;
2638 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2640 /* This code should be kept in sync with ModestRecptEditor. The
2641 textview inside the recpt editor is the one that really gets the
2642 focus. As it's inside a scrolled window, and this one inside the
2643 hbox recpt editor inherits from, we'll need to go up in the
2644 hierarchy to know if the text view is part of the recpt editor
2645 or if it's a different text entry */
2647 if (gtk_widget_get_parent (view_focus)) {
2648 GtkWidget *first_parent;
2650 first_parent = gtk_widget_get_parent (view_focus);
2651 if (gtk_widget_get_parent (first_parent) &&
2652 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2653 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2658 editor = MODEST_RECPT_EDITOR (priv->to_field);
2662 modest_address_book_select_addresses (editor);
2667 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2669 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2671 modest_msg_edit_window_open_addressbook (window, NULL);
2675 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2676 gboolean show_toolbar)
2678 ModestWindowPrivate *parent_priv;
2680 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2681 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2683 /* We can not just use the code of
2684 modest_msg_edit_window_setup_toolbar because it has a
2685 mixture of both initialization and creation code. */
2687 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2689 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2693 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2694 TnyHeaderFlags priority_flags)
2696 ModestMsgEditWindowPrivate *priv;
2697 ModestWindowPrivate *parent_priv;
2699 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2701 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2702 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2704 if (priv->priority_flags != priority_flags) {
2705 GtkAction *priority_action = NULL;
2707 priv->priority_flags = priority_flags;
2709 switch (priority_flags) {
2710 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2711 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), MODEST_HEADER_ICON_HIGH, GTK_ICON_SIZE_MENU);
2712 gtk_widget_show (priv->priority_icon);
2713 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2714 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2716 case TNY_HEADER_FLAG_LOW_PRIORITY:
2717 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "MODEST_HEADER_ICON_LOW", GTK_ICON_SIZE_MENU);
2718 gtk_widget_show (priv->priority_icon);
2719 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2720 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2723 gtk_widget_hide (priv->priority_icon);
2724 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2725 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2728 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2729 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2734 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2737 ModestMsgEditWindowPrivate *priv;
2738 ModestWindowPrivate *parent_priv;
2739 gint current_format;
2741 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2743 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2744 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2746 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2747 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2749 if (current_format != file_format) {
2750 switch (file_format) {
2751 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2752 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2753 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
2755 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2759 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2760 response = gtk_dialog_run (GTK_DIALOG (dialog));
2761 gtk_widget_destroy (dialog);
2762 if (response == GTK_RESPONSE_OK) {
2763 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2765 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu"));
2766 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
2771 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2772 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2773 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2778 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2781 ModestMsgEditWindowPrivate *priv;
2782 WPTextBufferFormat oldfmt, fmt;
2783 gint old_position = 0;
2787 GdkColor *color = NULL;
2788 gboolean bold, bold_set, italic, italic_set;
2789 gboolean underline, underline_set;
2790 gboolean strikethrough, strikethrough_set;
2791 gboolean position_set;
2792 gboolean font_size_set, font_set, color_set;
2795 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2796 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2798 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2799 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(),
2800 GTK_WINDOW(dialog), GTK_WINDOW (window));
2802 /* First we get the currently selected font information */
2803 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2805 switch (oldfmt.text_position) {
2806 case TEXT_POSITION_NORMAL:
2809 case TEXT_POSITION_SUPERSCRIPT:
2817 g_object_set (G_OBJECT (dialog),
2818 "bold", oldfmt.bold != FALSE,
2819 "bold-set", !oldfmt.cs.bold,
2820 "underline", oldfmt.underline != FALSE,
2821 "underline-set", !oldfmt.cs.underline,
2822 "italic", oldfmt.italic != FALSE,
2823 "italic-set", !oldfmt.cs.italic,
2824 "strikethrough", oldfmt.strikethrough != FALSE,
2825 "strikethrough-set", !oldfmt.cs.strikethrough,
2826 "color", &oldfmt.color,
2827 "color-set", !oldfmt.cs.color,
2828 "size", wp_font_size[oldfmt.font_size],
2829 "size-set", !oldfmt.cs.font_size,
2830 "position", old_position,
2831 "position-set", !oldfmt.cs.text_position,
2832 "family", wp_get_font_name (oldfmt.font),
2833 "family-set", !oldfmt.cs.font,
2836 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2837 GTK_WINDOW (dialog), GTK_WINDOW (window));
2838 gtk_widget_show_all (dialog);
2839 priv->font_dialog = dialog;
2840 response = gtk_dialog_run (GTK_DIALOG (dialog));
2841 priv->font_dialog = NULL;
2842 if (response == GTK_RESPONSE_OK) {
2844 g_object_get( dialog,
2846 "bold-set", &bold_set,
2847 "underline", &underline,
2848 "underline-set", &underline_set,
2850 "italic-set", &italic_set,
2851 "strikethrough", &strikethrough,
2852 "strikethrough-set", &strikethrough_set,
2854 "color-set", &color_set,
2856 "size-set", &font_size_set,
2857 "family", &font_name,
2858 "family-set", &font_set,
2859 "position", &position,
2860 "position-set", &position_set,
2865 if (response == GTK_RESPONSE_OK) {
2866 memset(&fmt, 0, sizeof(fmt));
2872 fmt.italic = italic;
2873 fmt.cs.italic = TRUE;
2875 if (underline_set) {
2876 fmt.underline = underline;
2877 fmt.cs.underline = TRUE;
2879 if (strikethrough_set) {
2880 fmt.strikethrough = strikethrough;
2881 fmt.cs.strikethrough = TRUE;
2886 ? TEXT_POSITION_NORMAL
2887 : ( ( position == 1 )
2888 ? TEXT_POSITION_SUPERSCRIPT
2889 : TEXT_POSITION_SUBSCRIPT );
2890 fmt.cs.text_position = TRUE;
2891 fmt.font_size = oldfmt.font_size;
2895 fmt.cs.color = TRUE;
2898 fmt.font = wp_get_font_index(font_name,
2903 if (font_size_set) {
2904 fmt.cs.font_size = TRUE;
2905 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
2907 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2908 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2910 gtk_widget_destroy (dialog);
2912 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2916 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2918 ModestMsgEditWindowPrivate *priv;
2920 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2921 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2923 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2925 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2926 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2930 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2932 ModestMsgEditWindowPrivate *priv;
2934 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2935 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2937 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2939 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2940 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2945 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2947 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2949 priv->can_undo = can_undo;
2953 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2955 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2957 priv->can_redo = can_redo;
2961 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
2963 ModestMsgEditWindowPrivate *priv;
2964 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2965 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2967 return priv->can_undo;
2971 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
2973 ModestMsgEditWindowPrivate *priv;
2974 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2975 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2977 return priv->can_redo;
2982 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2985 GtkTextIter match_start, match_end;
2987 if (image_id == NULL)
2990 gtk_text_buffer_get_start_iter (buffer, &iter);
2992 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2993 GSList *tags = gtk_text_iter_get_tags (&match_start);
2995 for (node = tags; node != NULL; node = g_slist_next (node)) {
2996 GtkTextTag *tag = (GtkTextTag *) node->data;
2997 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2998 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2999 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
3001 offset = gtk_text_iter_get_offset (&match_start);
3002 gtk_text_buffer_delete (buffer, &match_start, &match_end);
3003 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
3007 gtk_text_iter_forward_char (&iter);
3012 message_is_empty (ModestMsgEditWindow *window)
3014 ModestMsgEditWindowPrivate *priv = NULL;
3016 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3017 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3019 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
3020 * so we can ignore markup.
3022 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
3025 count = gtk_text_buffer_get_char_count (buf);
3031 msg_body_focus (GtkWidget *focus,
3032 GdkEventFocus *event,
3036 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3037 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3038 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3043 recpt_field_changed (GtkTextBuffer *buffer,
3044 ModestMsgEditWindow *editor)
3046 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3047 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3051 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3053 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3054 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3058 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3061 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3062 GtkTextBuffer *buffer;
3064 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3065 gtk_text_buffer_set_modified (buffer, modified);
3066 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3067 gtk_text_buffer_set_modified (buffer, modified);
3068 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3069 gtk_text_buffer_set_modified (buffer, modified);
3070 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3074 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3076 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3077 const char *account_name;
3078 GtkTextBuffer *buffer;
3080 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3081 if (gtk_text_buffer_get_modified (buffer))
3083 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3084 if (gtk_text_buffer_get_modified (buffer))
3086 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3087 if (gtk_text_buffer_get_modified (buffer))
3089 if (gtk_text_buffer_get_modified (priv->text_buffer))
3091 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3092 if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3103 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3105 ModestMsgEditWindowPrivate *priv = NULL;
3107 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3108 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3110 /* check if there's no recipient added */
3111 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3112 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3113 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3114 /* no recipient contents, then select contacts */
3115 modest_msg_edit_window_open_addressbook (window, NULL);
3119 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3120 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3123 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3124 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3127 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3128 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3132 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3133 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3134 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3141 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3142 ModestMsgEditWindow *window)
3144 modest_msg_edit_window_offer_attach_file (window);
3148 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3150 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3152 return priv->clipboard_text;
3156 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3158 ModestMsgEditWindow *window)
3160 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3161 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3163 if (!GTK_WIDGET_VISIBLE (window))
3166 g_object_ref (window);
3167 text = gtk_clipboard_wait_for_text (selection_clipboard);
3169 if (priv->clipboard_text != NULL) {
3170 g_free (priv->clipboard_text);
3172 priv->clipboard_text = text;
3174 if (GTK_WIDGET_VISIBLE (window)) {
3175 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3177 g_object_unref (window);
3180 static gboolean clipboard_owner_change_idle (gpointer userdata)
3182 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
3183 ModestMsgEditWindowPrivate *priv;
3185 gdk_threads_enter ();
3186 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3187 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3189 priv->clipboard_owner_idle = 0;
3190 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, window);
3191 gdk_threads_leave ();
3197 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window)
3199 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3200 if (priv->clipboard_owner_idle == 0) {
3201 priv->clipboard_owner_idle = g_idle_add (clipboard_owner_change_idle, window);
3206 subject_field_move_cursor (GtkEntry *entry,
3207 GtkMovementStep step,
3212 if (!GTK_WIDGET_VISIBLE (window))
3215 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3219 update_window_title (ModestMsgEditWindow *window)
3221 ModestMsgEditWindowPrivate *priv = NULL;
3222 const gchar *subject;
3224 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3225 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3226 if (subject == NULL || subject[0] == '\0')
3227 subject = _("mail_va_new_email");
3229 gtk_window_set_title (GTK_WINDOW (window), subject);
3234 subject_field_changed (GtkEditable *editable,
3235 ModestMsgEditWindow *window)
3237 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3238 update_window_title (window);
3239 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3240 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3241 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3245 subject_field_insert_text (GtkEditable *editable,
3247 gint new_text_length,
3249 ModestMsgEditWindow *window)
3251 GString *result = g_string_new ("");
3253 gint result_len = 0;
3254 const gchar *entry_text = NULL;
3257 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3258 old_length = g_utf8_strlen (entry_text, -1);
3260 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3261 gunichar c = g_utf8_get_char_validated (current, 8);
3262 /* Invalid unichar, stop */
3268 result = g_string_append_unichar (result, c);
3272 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3273 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3276 /* Prevent endless recursion */
3277 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3278 g_signal_emit_by_name (editable, "insert-text",
3279 (gpointer) result->str, (gpointer) result->len,
3280 (gpointer) position, (gpointer) window);
3281 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3285 if (result_len + old_length > 1000) {
3286 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3287 dgettext("hildon-common-strings",
3288 "ckdg_ib_maximum_characters_reached"));
3291 g_string_free (result, TRUE);
3295 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3298 ModestMsgEditWindowPrivate *priv = NULL;
3300 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3301 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3303 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3306 gtk_widget_show_all (priv->find_toolbar);
3307 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3309 gtk_widget_hide_all (priv->find_toolbar);
3310 gtk_widget_grab_focus (priv->msg_body);
3316 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3318 GtkTextIter *match_start,
3319 GtkTextIter *match_end)
3321 GtkTextIter end_iter;
3322 gchar *str_casefold;
3325 gchar *range_casefold;
3328 gboolean result = FALSE;
3335 gtk_text_iter_forward_to_end (&end_iter);
3337 str_casefold = g_utf8_casefold (str, -1);
3338 str_chars_n = strlen (str);
3340 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3341 range_casefold = g_utf8_casefold (range_text, -1);
3342 range_chars_n = strlen (range_casefold);
3344 if (range_chars_n < str_chars_n) {
3345 g_free (str_casefold);
3346 g_free (range_text);
3347 g_free (range_casefold);
3351 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3352 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3353 if (!g_utf8_collate (range_subtext, str_casefold)) {
3354 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3356 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3357 match_start, match_end, NULL);
3358 g_free (found_text);
3360 g_free (range_subtext);
3364 g_free (str_casefold);
3365 g_free (range_text);
3366 g_free (range_casefold);
3373 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3374 ModestMsgEditWindow *window)
3376 gchar *current_search = NULL;
3377 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3379 GtkTextIter selection_start, selection_end;
3380 GtkTextIter match_start, match_end;
3381 gboolean continue_search = FALSE;
3383 if (message_is_empty (window)) {
3384 g_free (priv->last_search);
3385 priv->last_search = NULL;
3386 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3390 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3391 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3392 g_free (current_search);
3393 g_free (priv->last_search);
3394 priv->last_search = NULL;
3395 /* Information banner about empty search */
3396 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
3400 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3401 continue_search = TRUE;
3403 g_free (priv->last_search);
3404 priv->last_search = g_strdup (current_search);
3407 if (continue_search) {
3408 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3409 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3410 &match_start, &match_end);
3412 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
3414 GtkTextIter buffer_start;
3415 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3416 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3417 &match_start, &match_end);
3419 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
3422 /* Mark as selected the string found in search */
3424 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3425 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3426 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3428 g_free (priv->last_search);
3429 priv->last_search = NULL;
3431 g_free (current_search);
3435 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3436 ModestMsgEditWindow *window)
3438 GtkToggleAction *toggle;
3439 ModestWindowPrivate *parent_priv;
3440 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3442 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
3443 gtk_toggle_action_set_active (toggle, FALSE);
3447 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3449 ModestMsgEditWindowPrivate *priv;
3451 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3456 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3459 ModestMsgEditWindowPrivate *priv;
3461 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3467 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3470 ModestMsgEditWindowPrivate *priv;
3471 TnyHeader *header = NULL;
3473 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3474 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3476 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3477 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3479 if (priv->draft_msg != NULL) {
3480 g_object_unref (priv->draft_msg);
3483 if (draft != NULL) {
3484 g_object_ref (draft);
3485 header = tny_msg_get_header (draft);
3486 if (priv->msg_uid) {
3487 g_free (priv->msg_uid);
3488 priv->msg_uid = NULL;
3490 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3491 if (GTK_WIDGET_REALIZED (window)) {
3492 if (!modest_window_mgr_register_window (mgr, MODEST_WINDOW (window), NULL)) {
3493 gtk_widget_destroy (GTK_WIDGET (window));
3499 priv->draft_msg = draft;
3503 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3504 GtkTextIter *start, GtkTextIter *end,
3507 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3508 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3511 if (tag == NULL) return;
3512 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3513 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3514 replace_with_images (window, priv->images);
3519 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3522 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3524 g_return_if_fail (TNY_IS_MIME_PART (part));
3525 tny_list_prepend (priv->attachments, (GObject *) part);
3526 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3527 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3528 gtk_widget_show_all (priv->attachments_caption);
3529 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3533 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3535 ModestMsgEditWindowPrivate *priv;
3537 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3538 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3540 return priv->msg_uid;
3544 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3545 ModestMsgEditWindowWidgetType widget_type)
3547 ModestMsgEditWindowPrivate *priv;
3549 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3550 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3552 switch (widget_type) {
3553 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3554 return priv->msg_body;
3556 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3557 return priv->to_field;
3559 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3560 return priv->cc_field;
3562 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3563 return priv->bcc_field;
3565 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3566 return priv->subject_field;
3568 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3569 return priv->attachments_view;
3577 remove_tags (WPTextBuffer *buffer)
3579 GtkTextIter start, end;
3581 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3582 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3584 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3588 on_account_removed (TnyAccountStore *account_store,
3589 TnyAccount *account,
3592 /* Do nothing if it's a store account, because we use the
3593 transport to send the messages */
3594 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3595 const gchar *parent_acc = NULL;
3596 const gchar *our_acc = NULL;
3598 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3599 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3600 /* Close this window if I'm showing a message of the removed account */
3601 if (strcmp (parent_acc, our_acc) == 0)
3602 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3607 on_zoom_minus_plus_not_implemented (ModestWindow *window)
3609 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3611 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
3617 set_zoom_do_nothing (ModestWindow *window,
3623 get_zoom_do_nothing (ModestWindow *window)