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 if (!is_wp_text_buffer_started) {
425 is_wp_text_buffer_started = TRUE;
426 wp_text_buffer_library_init ();
431 hildon_program_add_window (hildon_program_get_instance(),
437 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
439 static ModestPairList*
440 get_transports (void)
442 GSList *transports = NULL;
444 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
445 GSList *accounts = modest_account_mgr_account_names (account_mgr,
446 TRUE /* only enabled accounts. */);
448 GSList *cursor = accounts;
450 gchar *account_name = cursor->data;
451 gchar *from_string = NULL;
453 from_string = modest_account_mgr_get_from_string (account_mgr,
457 if (from_string && account_name) {
458 gchar *name = account_name;
459 ModestPair *pair = modest_pair_new ((gpointer) name,
460 (gpointer) from_string , TRUE);
461 transports = g_slist_prepend (transports, pair);
464 cursor = cursor->next;
466 g_slist_free (accounts); /* only free the accounts, not the elements,
467 * because they are used in the pairlist */
471 static void window_focus (GtkWindow *window,
475 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
479 scroll_drag_timeout (gpointer userdata)
481 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
482 ModestMsgEditWindowPrivate *priv;
484 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
486 correct_scroll_without_drag_check (win, TRUE);
488 priv->scroll_drag_timeout_id = 0;
494 correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused)
496 ModestMsgEditWindowPrivate *priv;
499 GdkRectangle rectangle;
505 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
507 if (only_if_focused && !gtk_widget_is_focus (priv->msg_body))
510 insert = gtk_text_buffer_get_insert (priv->text_buffer);
511 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
513 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
514 vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll));
515 offset = priv->msg_body->allocation.y;
517 new_value = vadj->value;
519 if ((offset + rectangle.y + rectangle.height) >
520 ((gint) (vadj->value +vadj->page_size))) {
521 new_value = (offset + rectangle.y) - vadj->page_size * 0.25;
522 if (new_value > vadj->upper - vadj->page_size)
523 new_value = vadj->upper - vadj->page_size;
524 } else if ((offset + rectangle.y) < ((gint) vadj->value)) {
525 new_value = (offset + rectangle.y - vadj->page_size * 0.75);
526 if (((gint) (new_value + vadj->page_size)) < (offset + rectangle.y + rectangle.height))
527 new_value = offset + rectangle.y + rectangle.height - (gint) vadj->page_size;
530 if (new_value > vadj->value)
531 new_value = vadj->value;
534 if (vadj->value != new_value) {
535 g_signal_emit_by_name (GTK_TEXT_VIEW(priv->msg_body)->layout,
537 vadj->value = new_value;
538 gtk_adjustment_value_changed (vadj);
539 /* invalidate body */
540 window = gtk_widget_get_parent_window (priv->msg_body);
542 gdk_window_invalidate_rect (window, NULL, TRUE);
548 correct_scroll (ModestMsgEditWindow *w)
550 ModestMsgEditWindowPrivate *priv;
552 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
553 if (gtk_grab_get_current () == priv->msg_body) {
554 if (priv->scroll_drag_timeout_id == 0) {
555 priv->scroll_drag_timeout_id = g_timeout_add (500, (GSourceFunc) scroll_drag_timeout,
561 correct_scroll_without_drag_check (w, TRUE);
565 text_buffer_end_user_action (GtkTextBuffer *buffer,
566 ModestMsgEditWindow *userdata)
569 correct_scroll (userdata);
573 text_buffer_mark_set (GtkTextBuffer *buffer,
576 ModestMsgEditWindow *userdata)
578 gtk_text_buffer_begin_user_action (buffer);
579 gtk_text_buffer_end_user_action (buffer);
583 cut_clipboard_check (GtkTextView *text_view,
586 GtkTextBuffer *buffer;
588 buffer = gtk_text_view_get_buffer (text_view);
589 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
590 g_signal_stop_emission_by_name ((gpointer )text_view, "cut-clipboard");
595 copy_clipboard_check (GtkTextView *text_view,
598 GtkTextBuffer *buffer;
600 buffer = gtk_text_view_get_buffer (text_view);
601 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
602 g_signal_stop_emission_by_name ((gpointer )text_view, "copy-clipboard");
607 vadj_changed (GtkAdjustment *adj,
608 ModestMsgEditWindow *window)
610 ModestMsgEditWindowPrivate *priv;
612 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
614 if (priv->last_upper != adj->upper) {
615 priv->last_upper = adj->upper;
616 correct_scroll (window);
621 attachment_deleted (ModestAttachmentsView *attachments_view,
624 modest_msg_edit_window_remove_attachments (MODEST_MSG_EDIT_WINDOW (user_data),
629 connect_signals (ModestMsgEditWindow *obj)
631 ModestMsgEditWindowPrivate *priv;
633 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
635 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
636 G_CALLBACK (text_buffer_refresh_attributes), obj);
637 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
638 G_CALLBACK (text_buffer_can_undo), obj);
639 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
640 G_CALLBACK (text_buffer_can_redo), obj);
641 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
642 G_CALLBACK (body_changed), obj);
643 g_signal_connect (G_OBJECT (priv->text_buffer), "modified-changed",
644 G_CALLBACK (body_changed), obj);
645 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
646 G_CALLBACK (text_buffer_end_user_action), obj);
647 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
648 G_CALLBACK (text_buffer_mark_set), obj);
649 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
650 G_CALLBACK (text_buffer_apply_tag), obj);
651 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
652 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
653 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
654 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
655 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
656 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
658 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
659 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
661 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
662 G_CALLBACK (msg_body_focus), obj);
663 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
664 G_CALLBACK (msg_body_focus), obj);
665 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
666 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
667 "changed", G_CALLBACK (recpt_field_changed), obj);
668 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
669 "changed", G_CALLBACK (recpt_field_changed), obj);
670 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
671 "changed", G_CALLBACK (recpt_field_changed), obj);
672 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
673 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
674 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
676 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
677 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
679 g_signal_connect (G_OBJECT (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll))),
681 G_CALLBACK (vadj_changed),
684 priv->clipboard_change_handler_id =
685 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
686 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
687 priv->default_clipboard_change_handler_id =
688 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
689 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
691 g_signal_connect (G_OBJECT (priv->msg_body), "cut-clipboard", G_CALLBACK (cut_clipboard_check), NULL);
692 g_signal_connect (G_OBJECT (priv->msg_body), "copy-clipboard", G_CALLBACK (copy_clipboard_check), NULL);
693 g_signal_connect (G_OBJECT (priv->attachments_view), "delete", G_CALLBACK (attachment_deleted), obj);
697 init_window (ModestMsgEditWindow *obj)
699 GtkWidget *to_caption, *subject_caption;
700 GtkWidget *main_vbox;
701 ModestMsgEditWindowPrivate *priv;
702 GtkActionGroup *action_group;
703 ModestWindowPrivate *parent_priv;
704 GdkPixbuf *window_icon = NULL;
705 GError *error = NULL;
707 GtkSizeGroup *title_size_group;
708 GtkSizeGroup *value_size_group;
709 GtkWidget *subject_box;
710 GtkWidget *attachment_icon;
711 GtkWidget *window_box;
712 #if (GTK_MINOR_VERSION >= 10)
713 GdkAtom deserialize_type;
716 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
717 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
719 parent_priv->ui_manager = gtk_ui_manager_new();
720 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
721 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
723 /* Add common actions */
724 gtk_action_group_add_actions (action_group,
725 modest_msg_edit_action_entries,
726 G_N_ELEMENTS (modest_msg_edit_action_entries),
728 gtk_action_group_add_toggle_actions (action_group,
729 modest_msg_edit_toggle_action_entries,
730 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
732 gtk_action_group_add_radio_actions (action_group,
733 modest_msg_edit_alignment_radio_action_entries,
734 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
736 G_CALLBACK (modest_ui_actions_on_change_justify),
738 gtk_action_group_add_radio_actions (action_group,
739 modest_msg_edit_priority_action_entries,
740 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
742 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
744 gtk_action_group_add_radio_actions (action_group,
745 modest_msg_edit_file_format_action_entries,
746 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
747 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
748 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
750 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
751 g_object_unref (action_group);
753 /* Load the UI definition */
754 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
757 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
758 g_clear_error (&error);
761 /* Add accelerators */
762 gtk_window_add_accel_group (GTK_WINDOW (obj),
763 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
765 parent_priv->menubar = NULL;
767 title_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
768 value_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
770 /* Note: This ModestPairList* must exist for as long as the picker
771 * that uses it, because the ModestSelectorPicker uses the ID opaquely,
772 * so it can't know how to manage its memory. */
773 priv->from_field = modest_selector_picker_new (MODEST_EDITABLE_SIZE,
774 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
776 modest_maemo_utils_set_hbutton_layout (title_size_group, value_size_group,
777 _("mail_va_from"), priv->from_field);
779 priv->to_field = modest_recpt_editor_new ();
780 priv->cc_field = modest_recpt_editor_new ();
781 priv->bcc_field = modest_recpt_editor_new ();
782 subject_box = gtk_hbox_new (FALSE, 0);
783 priv->priority_icon = gtk_image_new ();
784 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
785 priv->subject_field = hildon_entry_new (MODEST_EDITABLE_SIZE);
786 gtk_entry_set_max_length (GTK_ENTRY (priv->subject_field) ,SUBJECT_MAX_LENGTH);
787 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
788 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
789 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
790 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
791 priv->add_attachment_button = gtk_button_new ();
792 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
793 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
794 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
795 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 0.5);
796 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
797 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
798 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
799 priv->attachments_view = modest_attachments_view_new (NULL);
801 priv->header_box = gtk_vbox_new (FALSE, 0);
803 to_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
804 _("mail_va_to"), priv->to_field);
805 priv->cc_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
806 _("mail_va_cc"), priv->cc_field);
807 priv->bcc_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
808 _("mail_va_hotfix1"), priv->bcc_field);
809 subject_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
810 _("mail_va_subject"), subject_box);
811 priv->attachments_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
812 _("mail_va_attachment"),
813 priv->attachments_view);
814 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), value_size_group); */
815 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), value_size_group); */
816 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), value_size_group); */
817 g_object_unref (title_size_group);
818 g_object_unref (value_size_group);
820 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->from_field, FALSE, FALSE, 0);
821 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
822 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
823 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
824 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
825 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
826 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
829 priv->msg_body = wp_text_view_new ();
830 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
831 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
832 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
833 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
834 #if (GTK_MINOR_VERSION >= 10)
835 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), NULL);
836 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
838 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
839 deserialize_type, TRUE);
841 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
843 priv->find_toolbar = hildon_find_toolbar_new (NULL);
844 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
846 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
848 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
849 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
850 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
851 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->scroll), TRUE);
853 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
855 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
856 priv->frame = gtk_frame_new (NULL);
857 gtk_box_pack_start (GTK_BOX(main_vbox), priv->frame, TRUE, TRUE, 0);
859 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
860 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
861 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
863 window_box = gtk_vbox_new (FALSE, 0);
864 gtk_container_add (GTK_CONTAINER(obj), window_box);
866 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
868 gtk_container_add (GTK_CONTAINER (priv->frame), priv->msg_body);
870 /* Set window icon */
871 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
873 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
874 g_object_unref (window_icon);
879 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
881 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
883 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
884 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
885 priv->clipboard_change_handler_id))
886 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
887 priv->clipboard_change_handler_id);
888 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
889 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
890 priv->default_clipboard_change_handler_id))
891 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
892 priv->default_clipboard_change_handler_id);
894 if (priv->account_removed_handler_id &&
895 g_signal_handler_is_connected (modest_runtime_get_account_store (),
896 priv->account_removed_handler_id))
897 g_signal_handler_disconnect(modest_runtime_get_account_store (),
898 priv->account_removed_handler_id);
902 modest_msg_edit_window_finalize (GObject *obj)
904 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
906 /* Sanity check: shouldn't be needed, the window mgr should
907 call this function before */
908 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
910 if (priv->font_dialog != NULL) {
911 gtk_dialog_response (GTK_DIALOG (priv->font_dialog), GTK_RESPONSE_NONE);
914 if (priv->clipboard_text != NULL) {
915 g_free (priv->clipboard_text);
916 priv->clipboard_text = NULL;
919 if (priv->draft_msg != NULL) {
920 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
921 if (TNY_IS_HEADER (header)) {
922 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
923 modest_window_mgr_unregister_header (mgr, header);
925 g_object_unref (priv->draft_msg);
926 priv->draft_msg = NULL;
928 if (priv->outbox_msg != NULL) {
929 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
930 if (TNY_IS_HEADER (header)) {
931 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
932 modest_window_mgr_unregister_header (mgr, header);
934 g_object_unref (priv->outbox_msg);
935 priv->outbox_msg = NULL;
937 if (priv->scroll_drag_timeout_id > 0) {
938 g_source_remove (priv->scroll_drag_timeout_id);
939 priv->scroll_drag_timeout_id = 0;
941 if (priv->clipboard_owner_idle > 0) {
942 g_source_remove (priv->clipboard_owner_idle);
943 priv->clipboard_owner_idle = 0;
945 if (priv->original_account_name)
946 g_free (priv->original_account_name);
947 g_free (priv->msg_uid);
948 g_free (priv->last_search);
949 g_slist_free (priv->font_items_group);
950 g_slist_free (priv->size_items_group);
951 g_object_unref (priv->attachments);
952 g_object_unref (priv->images);
954 /* This had to stay alive for as long as the picker that used it: */
955 modest_pair_list_free (priv->from_field_protos);
957 G_OBJECT_CLASS(parent_class)->finalize (obj);
961 pixbuf_from_stream (TnyStream *stream, const gchar *mime_type, guint64 *stream_size)
963 GdkPixbufLoader *loader;
969 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
971 if (loader == NULL) {
977 tny_stream_reset (TNY_STREAM (stream));
978 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
979 GError *error = NULL;
980 unsigned char read_buffer[128];
982 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
984 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, &error)) {
986 g_error_free (error);
991 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
993 g_object_ref (pixbuf);
994 gdk_pixbuf_loader_close (loader, NULL);
995 g_object_unref (loader);
1000 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1001 GdkPixbuf *new_pixbuf;
1003 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1004 gdk_pixbuf_get_width (pixbuf);
1005 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1006 g_object_unref (pixbuf);
1007 pixbuf = new_pixbuf;
1011 *stream_size = size;
1017 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1019 ModestMsgEditWindowPrivate *priv;
1022 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1024 for (iter = tny_list_create_iterator (attachments);
1025 !tny_iterator_is_done (iter);
1026 tny_iterator_next (iter)) {
1027 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1028 const gchar *cid = tny_mime_part_get_content_id (part);
1029 const gchar *mime_type = tny_mime_part_get_content_type (part);
1030 if ((cid != NULL)&&(mime_type != NULL)) {
1031 guint64 stream_size;
1032 TnyStream *stream = tny_mime_part_get_decoded_stream (part);
1033 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
1036 g_object_unref (stream);
1038 if (pixbuf != NULL) {
1039 priv->images_count ++;
1040 priv->images_size += stream_size;
1041 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1042 g_object_unref (pixbuf);
1045 g_object_unref (part);
1047 g_object_unref (iter);
1051 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1053 TnyMimePart *parent = NULL;
1054 const gchar *content_type = NULL;
1055 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1057 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1059 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1060 parent = g_object_ref (msg);
1061 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1062 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1065 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1066 iter = tny_list_create_iterator (parts);
1067 while (!tny_iterator_is_done (iter)) {
1069 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1070 content_type = tny_mime_part_get_content_type (part);
1071 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1075 g_object_unref (part);
1077 tny_iterator_next (iter);
1079 g_object_unref (iter);
1080 g_object_unref (parts);
1083 if (parent != NULL) {
1084 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1087 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1088 iter = tny_list_create_iterator (parts);
1089 while (!tny_iterator_is_done (iter)) {
1091 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1092 content_type = tny_mime_part_get_content_type (part);
1093 if (content_type && g_str_has_prefix (content_type, "image/")) {
1094 tny_list_prepend (priv->images, (GObject *) part);
1096 g_object_unref (part);
1097 tny_iterator_next (iter);
1099 g_object_unref (iter);
1100 g_object_unref (parts);
1101 g_object_unref (parent);
1106 update_next_cid (ModestMsgEditWindow *self, TnyList *attachments)
1109 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1111 for (iter = tny_list_create_iterator (attachments) ;
1112 !tny_iterator_is_done (iter);
1113 tny_iterator_next (iter)) {
1114 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1115 const gchar *cid = tny_mime_part_get_content_id (part);
1117 char *invalid = NULL;
1118 gint int_cid = strtol (cid, &invalid, 10);
1119 if ((invalid != NULL) && (*invalid == '\0') && (int_cid >= priv->next_cid)) {
1120 priv->next_cid = int_cid + 1;
1123 g_object_unref (part);
1125 g_object_unref (iter);
1129 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1132 gchar *to, *cc, *bcc, *subject;
1134 ModestMsgEditWindowPrivate *priv;
1136 TnyHeaderFlags priority_flags;
1137 TnyFolder *msg_folder;
1138 gboolean is_html = FALSE;
1140 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1141 g_return_if_fail (TNY_IS_MSG (msg));
1143 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1145 header = tny_msg_get_header (msg);
1146 to = tny_header_dup_to (header);
1147 cc = tny_header_dup_cc (header);
1148 bcc = tny_header_dup_bcc (header);
1149 subject = tny_header_dup_subject (header);
1150 priority_flags = tny_header_get_priority (header);
1153 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1155 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1156 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1157 gtk_widget_show (priv->cc_caption);
1158 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1159 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1160 gtk_widget_hide (priv->cc_caption);
1163 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1164 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1165 gtk_widget_show (priv->bcc_caption);
1166 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1167 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1168 gtk_widget_hide (priv->bcc_caption);
1171 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1172 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1175 update_window_title (self);
1177 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1178 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1180 if ((body == NULL)||(body[0] == '\0')) {
1182 body = modest_text_utils_convert_to_html ("");
1185 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1186 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1189 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1192 /* Add attachments to the view */
1193 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1194 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1195 if (tny_list_get_length (priv->attachments) == 0) {
1196 gtk_widget_hide (priv->attachments_caption);
1198 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1199 gtk_widget_show_all (priv->attachments_caption);
1201 get_related_images (self, msg);
1202 update_next_cid (self, priv->attachments);
1203 update_next_cid (self, priv->images);
1204 replace_with_images (self, priv->images);
1206 if (preserve_is_rich && !is_html) {
1207 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1208 /* Get the default format required from configuration */
1209 } else if (!preserve_is_rich && !modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1210 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1213 /* Set the default focus depending on having already a To: field or not */
1214 if ((!to)||(*to == '\0')) {
1215 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1217 gtk_widget_grab_focus (priv->msg_body);
1220 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1222 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1223 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1225 modest_msg_edit_window_set_modified (self, FALSE);
1227 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1228 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1229 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1230 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1232 if (priv->msg_uid) {
1233 g_free (priv->msg_uid);
1234 priv->msg_uid = NULL;
1237 /* we should set a reference to the incoming message if it is a draft */
1238 msg_folder = tny_msg_get_folder (msg);
1240 if (modest_tny_folder_is_local_folder (msg_folder)) {
1241 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1242 if (type == TNY_FOLDER_TYPE_INVALID)
1243 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1245 if (type == TNY_FOLDER_TYPE_DRAFTS)
1246 priv->draft_msg = g_object_ref(msg);
1247 if (type == TNY_FOLDER_TYPE_OUTBOX)
1248 priv->outbox_msg = g_object_ref(msg);
1249 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1251 g_object_unref (msg_folder);
1261 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
1264 GList *item_children, *node;
1265 GtkWidget *bin_child;
1267 bin_child = gtk_bin_get_child (GTK_BIN(item));
1269 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
1271 for (node = item_children; node != NULL; node = g_list_next (node)) {
1272 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
1273 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
1276 g_list_free (item_children);
1280 menu_tool_button_dont_expand (GtkMenuToolButton *item)
1283 GList *item_children, *node;
1285 box = gtk_bin_get_child (GTK_BIN (item));
1286 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
1287 item_children = gtk_container_get_children (GTK_CONTAINER (box));
1289 for (node = item_children; node != NULL; node = g_list_next (node)) {
1290 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
1291 if (GTK_IS_TOGGLE_BUTTON (node->data))
1292 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
1293 else if (GTK_IS_BUTTON (node->data))
1294 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
1296 g_list_free (item_children);
1301 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1303 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1304 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1305 GtkWidget *placeholder;
1306 GtkWidget *tool_item;
1311 GtkWidget *sizes_menu;
1312 GtkWidget *fonts_menu;
1313 GSList *radio_group = NULL;
1314 GSList *node = NULL;
1318 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1319 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1321 /* Font color placeholder */
1322 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1323 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1326 tool_item = GTK_WIDGET (gtk_tool_item_new ());
1327 priv->font_color_button = hildon_color_button_new ();
1328 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
1329 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1330 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
1331 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1332 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1333 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1334 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1336 G_CALLBACK (modest_msg_edit_window_color_button_change),
1339 /* Font size and face placeholder */
1340 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1341 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1343 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1344 priv->size_tool_button_label = gtk_label_new (NULL);
1345 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1346 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1347 size_text,"</span>", NULL);
1348 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1350 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
1351 sizes_menu = gtk_menu_new ();
1352 priv->size_items_group = NULL;
1354 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1355 GtkWidget *size_menu_item;
1357 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1358 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
1359 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
1360 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
1361 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
1362 gtk_widget_show (size_menu_item);
1364 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
1368 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1369 GtkWidget *item = (GtkWidget *) node->data;
1370 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
1374 priv->size_items_group = g_slist_reverse (priv->size_items_group);
1375 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
1376 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1377 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1378 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1379 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1380 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1381 priv->font_size_toolitem = tool_item;
1384 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1385 priv->font_tool_button_label = gtk_label_new (NULL);
1386 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1387 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1389 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
1390 fonts_menu = gtk_menu_new ();
1391 priv->font_items_group = NULL;
1393 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1394 GtkWidget *font_menu_item;
1395 GtkWidget *child_label;
1397 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
1398 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
1399 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
1400 wp_get_font_name (font_index), "</span>", NULL);
1401 gtk_label_set_markup (GTK_LABEL (child_label), markup);
1404 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
1405 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
1406 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
1407 gtk_widget_show (font_menu_item);
1409 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
1412 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1413 GtkWidget *item = (GtkWidget *) node->data;
1414 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
1417 priv->font_items_group = g_slist_reverse (priv->font_items_group);
1418 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
1419 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1420 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1421 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1422 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1423 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1424 priv->font_face_toolitem = tool_item;
1426 /* Set expand and homogeneous for remaining items */
1427 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1428 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1429 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1430 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
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/ActionsItalics");
1434 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1435 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1437 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1438 will not show the tool items added to the placeholders) */
1439 gtk_widget_show_all (parent_priv->toolbar);
1441 /* Set the no show all *after* showing all items. We do not
1442 want the toolbar to be shown with a show all because it
1443 could go agains the gconf setting regarding showing or not
1444 the toolbar of the editor window */
1445 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1451 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean preserve_is_rich)
1454 ModestWindowPrivate *parent_priv;
1455 ModestMsgEditWindowPrivate *priv;
1456 ModestDimmingRulesGroup *menu_rules_group = NULL;
1457 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1458 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1459 ModestWindowMgr *mgr = NULL;
1461 g_return_val_if_fail (msg, NULL);
1462 g_return_val_if_fail (account_name, NULL);
1464 mgr = modest_runtime_get_window_mgr ();
1466 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1468 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1469 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1471 /* Menubar. Update the state of some toggles */
1472 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1473 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
1474 priv->from_field_protos = get_transports ();
1475 modest_selector_picker_set_pair_list (MODEST_SELECTOR_PICKER (priv->from_field), priv->from_field_protos);
1476 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1477 hildon_button_set_title (HILDON_BUTTON (priv->from_field),
1479 hildon_button_set_value (HILDON_BUTTON (priv->from_field),
1480 hildon_touch_selector_get_current_text
1481 (HILDON_TOUCH_SELECTOR (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (priv->from_field)))));
1482 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1483 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1486 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1488 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1490 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1492 priv->original_account_name = (account_name) ? g_strdup (account_name) : NULL;
1494 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new ();
1495 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1496 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1497 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1498 /* Add common dimming rules */
1499 modest_dimming_rules_group_add_rules (menu_rules_group,
1500 modest_msg_edit_window_menu_dimming_entries,
1501 G_N_ELEMENTS (modest_msg_edit_window_menu_dimming_entries),
1502 MODEST_WINDOW (obj));
1503 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1504 modest_msg_edit_window_toolbar_dimming_entries,
1505 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1506 MODEST_WINDOW (obj));
1507 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_button,
1508 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1509 MODEST_WINDOW (obj));
1510 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
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_face_toolitem,
1514 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1515 MODEST_WINDOW (obj));
1516 /* Insert dimming rules group for this window */
1517 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1518 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1519 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1520 /* Checks the dimming rules */
1521 g_object_unref (menu_rules_group);
1522 g_object_unref (toolbar_rules_group);
1523 g_object_unref (clipboard_rules_group);
1524 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1526 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1528 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1529 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1530 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1531 priv->update_caption_visibility = TRUE;
1533 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1535 /* Track account-removed signal, this window should be closed
1536 in the case we're creating a mail associated to the account
1538 priv->account_removed_handler_id =
1539 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1541 G_CALLBACK(on_account_removed),
1544 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (MODEST_MSG_EDIT_WINDOW (obj));
1546 return (ModestWindow*) obj;
1550 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1552 GString **string_buffer = (GString **) user_data;
1554 *string_buffer = g_string_append (*string_buffer, buffer);
1560 * @result: A new string which should be freed with g_free().
1563 get_formatted_data (ModestMsgEditWindow *edit_window)
1565 ModestMsgEditWindowPrivate *priv;
1566 GString *string_buffer = g_string_new ("");
1568 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1570 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1572 modest_text_utils_hyperlinkify (string_buffer);
1574 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1576 return g_string_free (string_buffer, FALSE);
1581 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1584 const gchar *account_name;
1585 ModestMsgEditWindowPrivate *priv;
1586 TnyIterator *att_iter;
1588 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1590 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1592 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1593 g_return_val_if_fail (account_name, NULL);
1596 /* don't free these (except from) */
1597 data = g_slice_new0 (MsgData);
1598 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1600 data->account_name = g_strdup (account_name);
1601 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1602 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1603 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1604 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1605 if (priv->draft_msg) {
1606 data->draft_msg = g_object_ref (priv->draft_msg);
1607 } else if (priv->outbox_msg) {
1608 data->draft_msg = g_object_ref (priv->outbox_msg);
1610 data->draft_msg = NULL;
1613 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1615 gtk_text_buffer_get_bounds (buf, &b, &e);
1616 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1618 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1619 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1621 data->html_body = NULL;
1623 /* deep-copy the data */
1624 att_iter = tny_list_create_iterator (priv->attachments);
1625 data->attachments = NULL;
1626 while (!tny_iterator_is_done (att_iter)) {
1627 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1628 if (!(TNY_IS_MIME_PART(part))) {
1629 g_warning ("strange data in attachment list");
1630 g_object_unref (part);
1631 tny_iterator_next (att_iter);
1634 data->attachments = g_list_append (data->attachments,
1636 tny_iterator_next (att_iter);
1638 g_object_unref (att_iter);
1640 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1641 att_iter = tny_list_create_iterator (priv->images);
1642 data->images = NULL;
1643 while (!tny_iterator_is_done (att_iter)) {
1644 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1646 if (!(TNY_IS_MIME_PART(part))) {
1647 g_warning ("strange data in attachment list");
1648 g_object_unref (part);
1649 tny_iterator_next (att_iter);
1652 cid = tny_mime_part_get_content_id (part);
1654 gchar *image_tag_id;
1655 GtkTextTag *image_tag;
1657 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1658 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1659 g_free (image_tag_id);
1661 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1663 ((gtk_text_iter_has_tag (&iter, image_tag))||
1664 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1665 data->images = g_list_append (data->images,
1666 g_object_ref (part));
1668 g_object_unref (part);
1669 tny_iterator_next (att_iter);
1671 g_object_unref (att_iter);
1673 data->priority_flags = priv->priority_flags;
1680 unref_gobject (GObject *obj, gpointer data)
1682 if (!G_IS_OBJECT(obj))
1684 g_object_unref (obj);
1688 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1691 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1699 g_free (data->from);
1700 g_free (data->subject);
1701 g_free (data->plain_body);
1702 g_free (data->html_body);
1703 g_free (data->account_name);
1705 if (data->draft_msg != NULL) {
1706 g_object_unref (data->draft_msg);
1707 data->draft_msg = NULL;
1710 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1711 g_list_free (data->attachments);
1712 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1713 g_list_free (data->images);
1715 g_slice_free (MsgData, data);
1719 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1721 guint64 *parts_size)
1723 ModestMsgEditWindowPrivate *priv;
1725 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1727 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1729 /* TODO: add images */
1730 *parts_size += priv->images_size;
1731 *parts_count += priv->images_count;
1736 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1739 ModestMsgEditWindowPrivate *priv = NULL;
1740 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1742 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1744 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1746 return MODEST_MSG_EDIT_FORMAT_HTML;
1748 return MODEST_MSG_EDIT_FORMAT_TEXT;
1752 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1753 ModestMsgEditFormat format)
1755 ModestMsgEditWindowPrivate *priv;
1757 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1758 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1761 case MODEST_MSG_EDIT_FORMAT_HTML:
1762 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1764 case MODEST_MSG_EDIT_FORMAT_TEXT:
1765 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1768 g_return_if_reached ();
1772 ModestMsgEditFormatState *
1773 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1775 ModestMsgEditFormatState *format_state = NULL;
1776 ModestMsgEditWindowPrivate *priv;
1777 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1779 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1780 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1782 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1784 format_state = g_new0 (ModestMsgEditFormatState, 1);
1785 format_state->bold = buffer_format->bold&0x1;
1786 format_state->italics = buffer_format->italic&0x1;
1787 format_state->bullet = buffer_format->bullet&0x1;
1788 format_state->color = buffer_format->color;
1789 format_state->font_size = buffer_format->font_size;
1790 format_state->font_family = wp_get_font_name (buffer_format->font);
1791 format_state->justification = buffer_format->justification;
1792 g_free (buffer_format);
1794 return format_state;
1799 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1800 const ModestMsgEditFormatState *format_state)
1802 ModestMsgEditWindowPrivate *priv;
1803 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1804 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1805 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1806 g_return_if_fail (format_state != NULL);
1808 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1809 gtk_widget_grab_focus (priv->msg_body);
1810 buffer_format->bold = (format_state->bold != FALSE);
1811 buffer_format->italic = (format_state->italics != FALSE);
1812 buffer_format->color = format_state->color;
1813 buffer_format->font_size = format_state->font_size;
1814 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1815 buffer_format->justification = format_state->justification;
1816 buffer_format->bullet = format_state->bullet;
1818 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1820 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1821 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1822 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1823 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1824 buffer_format->cs.font = (buffer_format->font != current_format->font);
1825 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1826 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1828 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1829 if (buffer_format->cs.bold) {
1830 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1831 GINT_TO_POINTER (buffer_format->bold&0x1));
1833 if (buffer_format->cs.italic) {
1834 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1835 GINT_TO_POINTER (buffer_format->italic&0x1));
1837 if (buffer_format->cs.color) {
1838 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1839 GINT_TO_POINTER (&(buffer_format->color)));
1841 if (buffer_format->cs.font_size) {
1842 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1843 GINT_TO_POINTER (buffer_format->font_size));
1845 if (buffer_format->cs.justification) {
1846 switch (buffer_format->justification) {
1847 case GTK_JUSTIFY_LEFT:
1848 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1849 GINT_TO_POINTER(TRUE));
1851 case GTK_JUSTIFY_CENTER:
1852 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1853 GINT_TO_POINTER(TRUE));
1855 case GTK_JUSTIFY_RIGHT:
1856 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1857 GINT_TO_POINTER(TRUE));
1864 if (buffer_format->cs.font) {
1865 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1866 GINT_TO_POINTER (buffer_format->font));
1868 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1869 if (buffer_format->cs.bullet) {
1870 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
1871 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
1873 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1875 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
1877 g_free (buffer_format);
1878 g_free (current_format);
1880 /* Check dimming rules */
1881 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1882 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1886 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1888 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1890 ModestWindowPrivate *parent_priv;
1891 ModestMsgEditWindowPrivate *priv;
1892 GtkWidget *new_size_menuitem;
1893 GtkWidget *new_font_menuitem;
1895 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1896 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1898 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1899 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu");
1900 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1901 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1903 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatPlainTextMenu");
1904 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1905 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1908 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1910 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1911 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1913 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1914 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1916 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
1917 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
1920 switch (buffer_format->justification)
1922 case GTK_JUSTIFY_LEFT:
1923 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1925 case GTK_JUSTIFY_CENTER:
1926 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1928 case GTK_JUSTIFY_RIGHT:
1929 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1936 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1938 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1939 G_CALLBACK (modest_msg_edit_window_color_button_change),
1941 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1942 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1943 G_CALLBACK (modest_msg_edit_window_color_button_change),
1946 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1947 buffer_format->font_size))->data);
1948 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1952 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1953 markup = g_strconcat ("<span font_family='Sans'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1954 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1956 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1957 G_CALLBACK (modest_msg_edit_window_size_change),
1959 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1960 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1961 G_CALLBACK (modest_msg_edit_window_size_change),
1965 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1966 buffer_format->font))->data);
1967 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1971 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1972 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1973 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1975 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1976 G_CALLBACK (modest_msg_edit_window_font_change),
1978 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1979 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1980 G_CALLBACK (modest_msg_edit_window_font_change),
1984 g_free (buffer_format);
1988 #ifdef MODEST_HILDON_VERSION_0
1990 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1993 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1994 ModestMsgEditWindowPrivate *priv;
1995 GtkWidget *dialog = NULL;
1997 GdkColor *new_color = NULL;
1999 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2000 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2002 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2003 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2004 g_free (buffer_format);
2006 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2007 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2008 if (new_color != NULL) {
2009 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2010 (gpointer) new_color);
2013 gtk_widget_destroy (dialog);
2018 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2021 ModestMsgEditWindowPrivate *priv;
2022 GtkWidget *dialog = NULL;
2024 GdkColor *old_color = NULL;
2025 const GdkColor *new_color = NULL;
2027 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2028 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2030 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2031 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2033 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2034 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2035 if (new_color != NULL)
2036 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2038 gtk_widget_destroy (dialog);
2044 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2047 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2048 ModestMsgEditWindowPrivate *priv;
2049 GtkWidget *dialog = NULL;
2051 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2052 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2054 dialog = hildon_color_chooser_new ();
2055 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2056 g_free (buffer_format);
2058 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2060 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2061 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2064 gtk_widget_destroy (dialog);
2069 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2072 ModestMsgEditWindowPrivate *priv;
2073 GtkWidget *dialog = NULL;
2074 GdkColor *old_color = NULL;
2076 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2077 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2079 dialog = hildon_color_chooser_new ();
2080 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2082 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2084 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2085 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2087 gtk_widget_destroy (dialog);
2090 #endif /*!MODEST_HILDON_VERSION_0*/
2095 create_stream_for_uri (const gchar* uri)
2100 TnyStream *result = NULL;
2102 GnomeVFSHandle *handle = NULL;
2103 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2104 if (test == GNOME_VFS_OK) {
2105 TnyStream *vfssstream = TNY_STREAM (tny_vfs_stream_new (handle));
2106 /* Streams over OBEX (Bluetooth) are not seekable but
2107 * we expect them to be (we might need to read them
2108 * several times). So if this is a Bluetooth URI just
2109 * read the whole file into memory (this is not a fast
2110 * protocol so we can assume that these files are not
2111 * going to be very big) */
2112 if ((g_ascii_strncasecmp (uri, "obex://", 7) == 0)||
2113 (g_ascii_strncasecmp (uri, "upnpav://", 9) == 0)) {
2114 TnyStream *memstream = tny_camel_mem_stream_new ();
2115 tny_stream_write_to_stream (vfssstream, memstream);
2116 g_object_unref (vfssstream);
2119 result = vfssstream;
2127 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2130 ModestMsgEditWindowPrivate *priv;
2131 GtkWidget *dialog = NULL;
2133 GSList *uris = NULL;
2134 GSList *uri_node = NULL;
2136 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2138 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2139 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2140 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2142 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2144 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2145 GTK_WINDOW (dialog), GTK_WINDOW (window));
2147 response = gtk_dialog_run (GTK_DIALOG (dialog));
2149 case GTK_RESPONSE_OK:
2150 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2155 gtk_widget_destroy (dialog);
2157 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2159 GnomeVFSHandle *handle = NULL;
2160 GnomeVFSResult result;
2161 GtkTextIter position;
2162 GtkTextMark *insert_mark;
2164 uri = (const gchar *) uri_node->data;
2165 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2166 if (result == GNOME_VFS_OK) {
2168 GnomeVFSFileInfo *info;
2169 gchar *filename, *basename, *escaped_filename;
2170 TnyMimePart *mime_part;
2172 const gchar *mime_type = NULL;
2173 GnomeVFSURI *vfs_uri;
2174 guint64 stream_size;
2176 gnome_vfs_close (handle);
2177 vfs_uri = gnome_vfs_uri_new (uri);
2179 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2180 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2181 g_free (escaped_filename);
2182 gnome_vfs_uri_unref (vfs_uri);
2183 info = gnome_vfs_file_info_new ();
2185 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2186 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2188 mime_type = gnome_vfs_file_info_get_mime_type (info);
2190 mime_part = tny_platform_factory_new_mime_part
2191 (modest_runtime_get_platform_factory ());
2193 TnyStream *stream = create_stream_for_uri (uri);
2195 if (stream == NULL) {
2197 modest_platform_information_banner (NULL, NULL, dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2199 g_object_unref (mime_part);
2200 gnome_vfs_file_info_unref (info);
2204 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2206 content_id = g_strdup_printf ("%d", priv->next_cid);
2207 tny_mime_part_set_content_id (mime_part, content_id);
2208 g_free (content_id);
2211 basename = g_path_get_basename (filename);
2212 tny_mime_part_set_filename (mime_part, basename);
2215 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
2217 if (pixbuf != NULL) {
2218 priv->images_size += stream_size;
2219 priv->images_count ++;
2220 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2221 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2222 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
2223 g_object_unref (pixbuf);
2226 tny_list_prepend (priv->images, (GObject *) mime_part);
2227 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2229 g_object_unref (mime_part);
2230 gnome_vfs_file_info_unref (info);
2239 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2241 GtkWidget *dialog = NULL;
2243 GSList *uris = NULL;
2245 GnomeVFSFileSize total_size, allowed_size;
2246 ModestMsgEditWindowPrivate *priv;
2250 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(window));
2252 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2254 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2257 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2258 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2259 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2260 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), GTK_WINDOW (window));
2262 response = gtk_dialog_run (GTK_DIALOG (dialog));
2264 case GTK_RESPONSE_OK:
2265 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2270 gtk_widget_destroy (dialog);
2272 /* allowed size is the maximum size - what's already there */
2273 modest_attachments_view_get_sizes (
2274 MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2275 &att_num, &att_size);
2276 allowed_size = MODEST_MAX_ATTACHMENT_SIZE - att_size;
2279 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2281 const gchar *uri = (const gchar *) uri_node->data;
2283 total_size += modest_msg_edit_window_attach_file_one
2284 (window, uri, allowed_size);
2286 if (total_size > allowed_size) {
2287 g_warning ("%s: total size: %u",
2288 __FUNCTION__, (unsigned int)total_size);
2292 allowed_size -= total_size;
2296 g_slist_foreach (uris, (GFunc) g_free, NULL);
2297 g_slist_free (uris);
2302 modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window,
2304 GnomeVFSFileSize allowed_size)
2307 GnomeVFSHandle *handle = NULL;
2308 ModestMsgEditWindowPrivate *priv;
2309 GnomeVFSResult result;
2310 GnomeVFSFileSize size = 0;
2311 g_return_val_if_fail (window, 0);
2312 g_return_val_if_fail (uri, 0);
2314 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2316 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2317 if (result == GNOME_VFS_OK) {
2318 TnyMimePart *mime_part;
2320 const gchar *mime_type = NULL;
2322 gchar *escaped_filename;
2325 GnomeVFSFileInfo *info;
2326 GnomeVFSURI *vfs_uri;
2328 gnome_vfs_close (handle);
2329 vfs_uri = gnome_vfs_uri_new (uri);
2332 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2333 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2334 g_free (escaped_filename);
2335 gnome_vfs_uri_unref (vfs_uri);
2337 info = gnome_vfs_file_info_new ();
2339 if (gnome_vfs_get_file_info (uri,
2341 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2343 mime_type = gnome_vfs_file_info_get_mime_type (info);
2344 mime_part = tny_platform_factory_new_mime_part
2345 (modest_runtime_get_platform_factory ());
2347 /* try to get the attachment's size; this may fail for weird
2348 * file systems, like obex, upnp... */
2349 if (allowed_size != 0 &&
2350 info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
2352 if (size > allowed_size) {
2353 modest_platform_information_banner (NULL, NULL,
2354 dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2358 g_warning ("%s: could not get attachment size", __FUNCTION__);
2360 stream = create_stream_for_uri (uri);
2362 if (stream == NULL) {
2364 modest_platform_information_banner (NULL, NULL, dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2366 g_object_unref (mime_part);
2367 gnome_vfs_file_info_unref (info);
2371 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2372 g_object_unref (stream);
2374 content_id = g_strdup_printf ("%d", priv->next_cid);
2375 tny_mime_part_set_content_id (mime_part, content_id);
2376 g_free (content_id);
2379 basename = g_path_get_basename (filename);
2380 tny_mime_part_set_filename (mime_part, basename);
2383 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2384 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2386 info->size == 0, info->size);
2387 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2388 gtk_widget_show_all (priv->attachments_caption);
2389 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2391 g_object_unref (mime_part);
2392 gnome_vfs_file_info_unref (info);
2399 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2402 ModestMsgEditWindowPrivate *priv;
2405 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2406 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2408 if (att_list == NULL) {
2409 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2411 g_object_ref (att_list);
2414 if (tny_list_get_length (att_list) == 0) {
2415 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2417 gboolean dialog_response;
2418 gchar *message = NULL;
2419 gchar *filename = NULL;
2421 if (tny_list_get_length (att_list) == 1) {
2423 iter = tny_list_create_iterator (att_list);
2424 part = (TnyMimePart *) tny_iterator_get_current (iter);
2425 g_object_unref (iter);
2426 if (TNY_IS_MSG (part)) {
2427 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2429 filename = tny_header_dup_subject (header);
2430 g_object_unref (header);
2432 if (filename == NULL) {
2433 filename = g_strdup (_("mail_va_no_subject"));
2436 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2438 g_object_unref (part);
2440 filename = g_strdup ("");
2442 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
2443 tny_list_get_length (att_list)), filename);
2446 dialog_response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window), message);
2449 if (dialog_response != GTK_RESPONSE_OK) {
2450 g_object_unref (att_list);
2453 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
2455 for (iter = tny_list_create_iterator (att_list);
2456 !tny_iterator_is_done (iter);
2457 tny_iterator_next (iter)) {
2458 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2459 const gchar *att_id;
2460 tny_list_remove (priv->attachments, (GObject *) mime_part);
2462 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2464 if (tny_list_get_length (priv->attachments) == 0)
2465 gtk_widget_hide (priv->attachments_caption);
2466 att_id = tny_mime_part_get_content_id (mime_part);
2468 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2470 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2471 g_object_unref (mime_part);
2473 g_object_unref (iter);
2476 g_object_unref (att_list);
2478 /* if the last attachment has been removed, focus the Subject: field */
2479 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2480 gtk_widget_grab_focus (priv->subject_field);
2484 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2487 ModestMsgEditWindowPrivate *priv;
2488 GdkColor *new_color;
2489 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2491 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2492 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2495 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2497 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2499 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2501 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2506 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
2509 ModestMsgEditWindowPrivate *priv;
2510 gint new_size_index;
2511 ModestMsgEditWindow *window;
2514 window = MODEST_MSG_EDIT_WINDOW (userdata);
2515 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2516 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2518 if (gtk_check_menu_item_get_active (menu_item)) {
2520 WPTextBufferFormat format;
2522 memset (&format, 0, sizeof (format));
2523 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2525 label = gtk_bin_get_child (GTK_BIN (menu_item));
2527 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
2528 format.cs.font_size = TRUE;
2529 format.cs.text_position = TRUE;
2530 format.cs.font = TRUE;
2531 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
2532 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2534 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2535 GINT_TO_POINTER (wp_get_font_size_index (new_size_index, 12))))
2536 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2538 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2539 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
2540 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2546 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
2549 ModestMsgEditWindowPrivate *priv;
2550 gint new_font_index;
2551 ModestMsgEditWindow *window;
2554 window = MODEST_MSG_EDIT_WINDOW (userdata);
2555 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2556 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2558 if (gtk_check_menu_item_get_active (menu_item)) {
2561 label = gtk_bin_get_child (GTK_BIN (menu_item));
2563 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
2565 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2566 GINT_TO_POINTER(new_font_index)))
2567 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2569 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2570 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2571 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2577 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2580 ModestMsgEditWindowPrivate *priv = NULL;
2581 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2583 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2584 if (!priv->update_caption_visibility)
2587 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2589 gtk_widget_show (priv->cc_caption);
2591 gtk_widget_hide (priv->cc_caption);
2593 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2597 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2600 ModestMsgEditWindowPrivate *priv = NULL;
2601 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2603 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2604 if (!priv->update_caption_visibility)
2607 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2609 gtk_widget_show (priv->bcc_caption);
2611 gtk_widget_hide (priv->bcc_caption);
2613 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2617 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2618 ModestRecptEditor *editor)
2620 ModestMsgEditWindowPrivate *priv;
2622 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2623 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2625 /* we check for low-mem; in that case, show a warning, and don't allow
2626 * for the addressbook
2628 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2631 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2633 if (editor == NULL) {
2634 GtkWidget *view_focus;
2635 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2637 /* This code should be kept in sync with ModestRecptEditor. The
2638 textview inside the recpt editor is the one that really gets the
2639 focus. As it's inside a scrolled window, and this one inside the
2640 hbox recpt editor inherits from, we'll need to go up in the
2641 hierarchy to know if the text view is part of the recpt editor
2642 or if it's a different text entry */
2644 if (gtk_widget_get_parent (view_focus)) {
2645 GtkWidget *first_parent;
2647 first_parent = gtk_widget_get_parent (view_focus);
2648 if (gtk_widget_get_parent (first_parent) &&
2649 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2650 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2655 editor = MODEST_RECPT_EDITOR (priv->to_field);
2659 modest_address_book_select_addresses (editor);
2664 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2666 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2668 modest_msg_edit_window_open_addressbook (window, NULL);
2672 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2673 gboolean show_toolbar)
2675 ModestWindowPrivate *parent_priv;
2677 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2678 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2680 /* We can not just use the code of
2681 modest_msg_edit_window_setup_toolbar because it has a
2682 mixture of both initialization and creation code. */
2684 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2686 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2690 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2691 TnyHeaderFlags priority_flags)
2693 ModestMsgEditWindowPrivate *priv;
2694 ModestWindowPrivate *parent_priv;
2696 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2698 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2699 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2701 if (priv->priority_flags != priority_flags) {
2702 GtkAction *priority_action = NULL;
2704 priv->priority_flags = priority_flags;
2706 switch (priority_flags) {
2707 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2708 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), MODEST_HEADER_ICON_HIGH, GTK_ICON_SIZE_MENU);
2709 gtk_widget_show (priv->priority_icon);
2710 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2711 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2713 case TNY_HEADER_FLAG_LOW_PRIORITY:
2714 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "MODEST_HEADER_ICON_LOW", GTK_ICON_SIZE_MENU);
2715 gtk_widget_show (priv->priority_icon);
2716 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2717 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2720 gtk_widget_hide (priv->priority_icon);
2721 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2722 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2725 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2726 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2731 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2734 ModestMsgEditWindowPrivate *priv;
2735 ModestWindowPrivate *parent_priv;
2736 gint current_format;
2738 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2740 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2741 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2743 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2744 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2746 if (current_format != file_format) {
2747 switch (file_format) {
2748 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2749 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2750 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
2752 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2756 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2757 response = gtk_dialog_run (GTK_DIALOG (dialog));
2758 gtk_widget_destroy (dialog);
2759 if (response == GTK_RESPONSE_OK) {
2760 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2762 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu"));
2763 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
2768 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2769 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2770 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2775 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2778 ModestMsgEditWindowPrivate *priv;
2779 WPTextBufferFormat oldfmt, fmt;
2780 gint old_position = 0;
2784 GdkColor *color = NULL;
2785 gboolean bold, bold_set, italic, italic_set;
2786 gboolean underline, underline_set;
2787 gboolean strikethrough, strikethrough_set;
2788 gboolean position_set;
2789 gboolean font_size_set, font_set, color_set;
2792 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2793 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2795 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2796 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(),
2797 GTK_WINDOW(dialog), GTK_WINDOW (window));
2799 /* First we get the currently selected font information */
2800 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2802 switch (oldfmt.text_position) {
2803 case TEXT_POSITION_NORMAL:
2806 case TEXT_POSITION_SUPERSCRIPT:
2814 g_object_set (G_OBJECT (dialog),
2815 "bold", oldfmt.bold != FALSE,
2816 "bold-set", !oldfmt.cs.bold,
2817 "underline", oldfmt.underline != FALSE,
2818 "underline-set", !oldfmt.cs.underline,
2819 "italic", oldfmt.italic != FALSE,
2820 "italic-set", !oldfmt.cs.italic,
2821 "strikethrough", oldfmt.strikethrough != FALSE,
2822 "strikethrough-set", !oldfmt.cs.strikethrough,
2823 "color", &oldfmt.color,
2824 "color-set", !oldfmt.cs.color,
2825 "size", wp_font_size[oldfmt.font_size],
2826 "size-set", !oldfmt.cs.font_size,
2827 "position", old_position,
2828 "position-set", !oldfmt.cs.text_position,
2829 "family", wp_get_font_name (oldfmt.font),
2830 "family-set", !oldfmt.cs.font,
2833 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2834 GTK_WINDOW (dialog), GTK_WINDOW (window));
2835 gtk_widget_show_all (dialog);
2836 priv->font_dialog = dialog;
2837 response = gtk_dialog_run (GTK_DIALOG (dialog));
2838 priv->font_dialog = NULL;
2839 if (response == GTK_RESPONSE_OK) {
2841 g_object_get( dialog,
2843 "bold-set", &bold_set,
2844 "underline", &underline,
2845 "underline-set", &underline_set,
2847 "italic-set", &italic_set,
2848 "strikethrough", &strikethrough,
2849 "strikethrough-set", &strikethrough_set,
2851 "color-set", &color_set,
2853 "size-set", &font_size_set,
2854 "family", &font_name,
2855 "family-set", &font_set,
2856 "position", &position,
2857 "position-set", &position_set,
2862 if (response == GTK_RESPONSE_OK) {
2863 memset(&fmt, 0, sizeof(fmt));
2869 fmt.italic = italic;
2870 fmt.cs.italic = TRUE;
2872 if (underline_set) {
2873 fmt.underline = underline;
2874 fmt.cs.underline = TRUE;
2876 if (strikethrough_set) {
2877 fmt.strikethrough = strikethrough;
2878 fmt.cs.strikethrough = TRUE;
2883 ? TEXT_POSITION_NORMAL
2884 : ( ( position == 1 )
2885 ? TEXT_POSITION_SUPERSCRIPT
2886 : TEXT_POSITION_SUBSCRIPT );
2887 fmt.cs.text_position = TRUE;
2888 fmt.font_size = oldfmt.font_size;
2892 fmt.cs.color = TRUE;
2895 fmt.font = wp_get_font_index(font_name,
2900 if (font_size_set) {
2901 fmt.cs.font_size = TRUE;
2902 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
2904 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2905 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2907 gtk_widget_destroy (dialog);
2909 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2913 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2915 ModestMsgEditWindowPrivate *priv;
2917 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2918 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2920 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2922 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2923 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2927 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2929 ModestMsgEditWindowPrivate *priv;
2931 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2932 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2934 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2936 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2937 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2942 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2944 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2946 priv->can_undo = can_undo;
2950 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2952 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2954 priv->can_redo = can_redo;
2958 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
2960 ModestMsgEditWindowPrivate *priv;
2961 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2962 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2964 return priv->can_undo;
2968 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
2970 ModestMsgEditWindowPrivate *priv;
2971 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2972 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2974 return priv->can_redo;
2979 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2982 GtkTextIter match_start, match_end;
2984 if (image_id == NULL)
2987 gtk_text_buffer_get_start_iter (buffer, &iter);
2989 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2990 GSList *tags = gtk_text_iter_get_tags (&match_start);
2992 for (node = tags; node != NULL; node = g_slist_next (node)) {
2993 GtkTextTag *tag = (GtkTextTag *) node->data;
2994 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2995 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2996 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2998 offset = gtk_text_iter_get_offset (&match_start);
2999 gtk_text_buffer_delete (buffer, &match_start, &match_end);
3000 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
3004 gtk_text_iter_forward_char (&iter);
3009 message_is_empty (ModestMsgEditWindow *window)
3011 ModestMsgEditWindowPrivate *priv = NULL;
3013 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3014 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3016 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
3017 * so we can ignore markup.
3019 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
3022 count = gtk_text_buffer_get_char_count (buf);
3028 msg_body_focus (GtkWidget *focus,
3029 GdkEventFocus *event,
3033 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3034 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3035 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3040 recpt_field_changed (GtkTextBuffer *buffer,
3041 ModestMsgEditWindow *editor)
3043 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3044 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3048 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3050 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3051 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3055 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3058 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3059 GtkTextBuffer *buffer;
3061 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3062 gtk_text_buffer_set_modified (buffer, modified);
3063 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3064 gtk_text_buffer_set_modified (buffer, modified);
3065 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3066 gtk_text_buffer_set_modified (buffer, modified);
3067 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3071 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3073 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3074 const char *account_name;
3075 GtkTextBuffer *buffer;
3077 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3078 if (gtk_text_buffer_get_modified (buffer))
3080 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3081 if (gtk_text_buffer_get_modified (buffer))
3083 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3084 if (gtk_text_buffer_get_modified (buffer))
3086 if (gtk_text_buffer_get_modified (priv->text_buffer))
3088 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3089 if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3100 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3102 ModestMsgEditWindowPrivate *priv = NULL;
3104 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3105 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3107 /* check if there's no recipient added */
3108 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3109 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3110 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3111 /* no recipient contents, then select contacts */
3112 modest_msg_edit_window_open_addressbook (window, NULL);
3116 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3117 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3120 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3121 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3124 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3125 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3129 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3130 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3131 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3138 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3139 ModestMsgEditWindow *window)
3141 modest_msg_edit_window_offer_attach_file (window);
3145 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3147 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3149 return priv->clipboard_text;
3153 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3155 ModestMsgEditWindow *window)
3157 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3158 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3160 if (!GTK_WIDGET_VISIBLE (window))
3163 g_object_ref (window);
3164 text = gtk_clipboard_wait_for_text (selection_clipboard);
3166 if (priv->clipboard_text != NULL) {
3167 g_free (priv->clipboard_text);
3169 priv->clipboard_text = text;
3171 if (GTK_WIDGET_VISIBLE (window)) {
3172 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3174 g_object_unref (window);
3177 static gboolean clipboard_owner_change_idle (gpointer userdata)
3179 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
3180 ModestMsgEditWindowPrivate *priv;
3182 gdk_threads_enter ();
3183 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3184 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3186 priv->clipboard_owner_idle = 0;
3187 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, window);
3188 gdk_threads_leave ();
3194 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window)
3196 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3197 if (priv->clipboard_owner_idle == 0) {
3198 priv->clipboard_owner_idle = g_idle_add (clipboard_owner_change_idle, window);
3203 subject_field_move_cursor (GtkEntry *entry,
3204 GtkMovementStep step,
3209 if (!GTK_WIDGET_VISIBLE (window))
3212 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3216 update_window_title (ModestMsgEditWindow *window)
3218 ModestMsgEditWindowPrivate *priv = NULL;
3219 const gchar *subject;
3221 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3222 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3223 if (subject == NULL || subject[0] == '\0')
3224 subject = _("mail_va_new_email");
3226 gtk_window_set_title (GTK_WINDOW (window), subject);
3231 subject_field_changed (GtkEditable *editable,
3232 ModestMsgEditWindow *window)
3234 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3235 update_window_title (window);
3236 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3237 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3238 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3242 subject_field_insert_text (GtkEditable *editable,
3244 gint new_text_length,
3246 ModestMsgEditWindow *window)
3248 GString *result = g_string_new ("");
3250 gint result_len = 0;
3251 const gchar *entry_text = NULL;
3254 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3255 old_length = g_utf8_strlen (entry_text, -1);
3257 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3258 gunichar c = g_utf8_get_char_validated (current, 8);
3259 /* Invalid unichar, stop */
3265 result = g_string_append_unichar (result, c);
3269 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3270 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3273 /* Prevent endless recursion */
3274 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3275 g_signal_emit_by_name (editable, "insert-text",
3276 (gpointer) result->str, (gpointer) result->len,
3277 (gpointer) position, (gpointer) window);
3278 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3282 if (result_len + old_length > 1000) {
3283 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3284 dgettext("hildon-common-strings",
3285 "ckdg_ib_maximum_characters_reached"));
3288 g_string_free (result, TRUE);
3292 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3295 ModestMsgEditWindowPrivate *priv = NULL;
3297 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3298 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3300 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3303 gtk_widget_show_all (priv->find_toolbar);
3304 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3306 gtk_widget_hide_all (priv->find_toolbar);
3307 gtk_widget_grab_focus (priv->msg_body);
3313 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3315 GtkTextIter *match_start,
3316 GtkTextIter *match_end)
3318 GtkTextIter end_iter;
3319 gchar *str_casefold;
3322 gchar *range_casefold;
3325 gboolean result = FALSE;
3332 gtk_text_iter_forward_to_end (&end_iter);
3334 str_casefold = g_utf8_casefold (str, -1);
3335 str_chars_n = strlen (str);
3337 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3338 range_casefold = g_utf8_casefold (range_text, -1);
3339 range_chars_n = strlen (range_casefold);
3341 if (range_chars_n < str_chars_n) {
3342 g_free (str_casefold);
3343 g_free (range_text);
3344 g_free (range_casefold);
3348 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3349 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3350 if (!g_utf8_collate (range_subtext, str_casefold)) {
3351 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3353 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3354 match_start, match_end, NULL);
3355 g_free (found_text);
3357 g_free (range_subtext);
3361 g_free (str_casefold);
3362 g_free (range_text);
3363 g_free (range_casefold);
3370 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3371 ModestMsgEditWindow *window)
3373 gchar *current_search = NULL;
3374 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3376 GtkTextIter selection_start, selection_end;
3377 GtkTextIter match_start, match_end;
3378 gboolean continue_search = FALSE;
3380 if (message_is_empty (window)) {
3381 g_free (priv->last_search);
3382 priv->last_search = NULL;
3383 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3387 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3388 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3389 g_free (current_search);
3390 g_free (priv->last_search);
3391 priv->last_search = NULL;
3392 /* Information banner about empty search */
3393 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
3397 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3398 continue_search = TRUE;
3400 g_free (priv->last_search);
3401 priv->last_search = g_strdup (current_search);
3404 if (continue_search) {
3405 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3406 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3407 &match_start, &match_end);
3409 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
3411 GtkTextIter buffer_start;
3412 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3413 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3414 &match_start, &match_end);
3416 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
3419 /* Mark as selected the string found in search */
3421 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3422 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3423 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3425 g_free (priv->last_search);
3426 priv->last_search = NULL;
3428 g_free (current_search);
3432 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3433 ModestMsgEditWindow *window)
3435 GtkToggleAction *toggle;
3436 ModestWindowPrivate *parent_priv;
3437 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3439 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
3440 gtk_toggle_action_set_active (toggle, FALSE);
3444 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3446 ModestMsgEditWindowPrivate *priv;
3448 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3453 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3456 ModestMsgEditWindowPrivate *priv;
3458 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3464 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3467 ModestMsgEditWindowPrivate *priv;
3468 TnyHeader *header = NULL;
3470 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3471 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3473 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3474 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3476 if (priv->draft_msg != NULL) {
3477 g_object_unref (priv->draft_msg);
3480 if (draft != NULL) {
3481 g_object_ref (draft);
3482 header = tny_msg_get_header (draft);
3483 if (priv->msg_uid) {
3484 g_free (priv->msg_uid);
3485 priv->msg_uid = NULL;
3487 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3488 if (GTK_WIDGET_REALIZED (window)) {
3489 if (!modest_window_mgr_register_window (mgr, MODEST_WINDOW (window), NULL)) {
3490 gtk_widget_destroy (GTK_WIDGET (window));
3496 priv->draft_msg = draft;
3500 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3501 GtkTextIter *start, GtkTextIter *end,
3504 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3505 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3508 if (tag == NULL) return;
3509 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3510 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3511 replace_with_images (window, priv->images);
3516 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3519 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3521 g_return_if_fail (TNY_IS_MIME_PART (part));
3522 tny_list_prepend (priv->attachments, (GObject *) part);
3523 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3524 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3525 gtk_widget_show_all (priv->attachments_caption);
3526 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3530 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3532 ModestMsgEditWindowPrivate *priv;
3534 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3535 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3537 return priv->msg_uid;
3541 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3542 ModestMsgEditWindowWidgetType widget_type)
3544 ModestMsgEditWindowPrivate *priv;
3546 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3547 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3549 switch (widget_type) {
3550 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3551 return priv->msg_body;
3553 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3554 return priv->to_field;
3556 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3557 return priv->cc_field;
3559 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3560 return priv->bcc_field;
3562 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3563 return priv->subject_field;
3565 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3566 return priv->attachments_view;
3574 remove_tags (WPTextBuffer *buffer)
3576 GtkTextIter start, end;
3578 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3579 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3581 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3585 on_account_removed (TnyAccountStore *account_store,
3586 TnyAccount *account,
3589 /* Do nothing if it's a store account, because we use the
3590 transport to send the messages */
3591 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3592 const gchar *parent_acc = NULL;
3593 const gchar *our_acc = NULL;
3595 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3596 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3597 /* Close this window if I'm showing a message of the removed account */
3598 if (strcmp (parent_acc, our_acc) == 0)
3599 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3604 on_zoom_minus_plus_not_implemented (ModestWindow *window)
3606 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3608 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
3614 set_zoom_do_nothing (ModestWindow *window,
3620 get_zoom_do_nothing (ModestWindow *window)