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_with_size_type
804 (title_size_group, value_size_group,
805 _("mail_va_to"), priv->to_field,
806 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
807 priv->cc_caption = modest_maemo_utils_create_captioned_with_size_type
808 (title_size_group, value_size_group,
809 _("mail_va_cc"), priv->cc_field,
810 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
811 priv->bcc_caption = modest_maemo_utils_create_captioned_with_size_type
812 (title_size_group, value_size_group,
813 _("mail_va_hotfix1"), priv->bcc_field,
814 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
815 subject_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
816 _("mail_va_subject"), subject_box);
817 priv->attachments_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
818 _("mail_va_attachment"),
819 priv->attachments_view);
820 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), value_size_group); */
821 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), value_size_group); */
822 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), value_size_group); */
823 g_object_unref (title_size_group);
824 g_object_unref (value_size_group);
826 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->from_field, FALSE, FALSE, 0);
827 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
828 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
829 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
830 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
831 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
832 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
835 priv->msg_body = wp_text_view_new ();
836 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
837 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
838 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
839 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
840 #if (GTK_MINOR_VERSION >= 10)
841 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), NULL);
842 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
844 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
845 deserialize_type, TRUE);
847 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
849 priv->find_toolbar = hildon_find_toolbar_new (NULL);
850 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
852 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
854 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
855 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
856 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
857 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->scroll), TRUE);
859 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
861 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
862 priv->frame = gtk_frame_new (NULL);
863 gtk_box_pack_start (GTK_BOX(main_vbox), priv->frame, TRUE, TRUE, 0);
865 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
866 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
867 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
869 window_box = gtk_vbox_new (FALSE, 0);
870 gtk_container_add (GTK_CONTAINER(obj), window_box);
872 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
874 gtk_container_add (GTK_CONTAINER (priv->frame), priv->msg_body);
876 /* Set window icon */
877 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
879 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
880 g_object_unref (window_icon);
885 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
887 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
889 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
890 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
891 priv->clipboard_change_handler_id))
892 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
893 priv->clipboard_change_handler_id);
894 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
895 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
896 priv->default_clipboard_change_handler_id))
897 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
898 priv->default_clipboard_change_handler_id);
900 if (priv->account_removed_handler_id &&
901 g_signal_handler_is_connected (modest_runtime_get_account_store (),
902 priv->account_removed_handler_id))
903 g_signal_handler_disconnect(modest_runtime_get_account_store (),
904 priv->account_removed_handler_id);
908 modest_msg_edit_window_finalize (GObject *obj)
910 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
912 /* Sanity check: shouldn't be needed, the window mgr should
913 call this function before */
914 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
916 if (priv->font_dialog != NULL) {
917 gtk_dialog_response (GTK_DIALOG (priv->font_dialog), GTK_RESPONSE_NONE);
920 if (priv->clipboard_text != NULL) {
921 g_free (priv->clipboard_text);
922 priv->clipboard_text = NULL;
925 if (priv->draft_msg != NULL) {
926 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
927 if (TNY_IS_HEADER (header)) {
928 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
929 modest_window_mgr_unregister_header (mgr, header);
931 g_object_unref (priv->draft_msg);
932 priv->draft_msg = NULL;
934 if (priv->outbox_msg != NULL) {
935 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
936 if (TNY_IS_HEADER (header)) {
937 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
938 modest_window_mgr_unregister_header (mgr, header);
940 g_object_unref (priv->outbox_msg);
941 priv->outbox_msg = NULL;
943 if (priv->scroll_drag_timeout_id > 0) {
944 g_source_remove (priv->scroll_drag_timeout_id);
945 priv->scroll_drag_timeout_id = 0;
947 if (priv->clipboard_owner_idle > 0) {
948 g_source_remove (priv->clipboard_owner_idle);
949 priv->clipboard_owner_idle = 0;
951 if (priv->original_account_name)
952 g_free (priv->original_account_name);
953 g_free (priv->msg_uid);
954 g_free (priv->last_search);
955 g_slist_free (priv->font_items_group);
956 g_slist_free (priv->size_items_group);
957 g_object_unref (priv->attachments);
958 g_object_unref (priv->images);
960 /* This had to stay alive for as long as the picker that used it: */
961 modest_pair_list_free (priv->from_field_protos);
963 G_OBJECT_CLASS(parent_class)->finalize (obj);
967 pixbuf_from_stream (TnyStream *stream, const gchar *mime_type, guint64 *stream_size)
969 GdkPixbufLoader *loader;
975 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
977 if (loader == NULL) {
983 tny_stream_reset (TNY_STREAM (stream));
984 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
985 GError *error = NULL;
986 unsigned char read_buffer[128];
988 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
990 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, &error)) {
992 g_error_free (error);
997 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
999 g_object_ref (pixbuf);
1000 gdk_pixbuf_loader_close (loader, NULL);
1001 g_object_unref (loader);
1006 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1007 GdkPixbuf *new_pixbuf;
1009 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1010 gdk_pixbuf_get_width (pixbuf);
1011 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1012 g_object_unref (pixbuf);
1013 pixbuf = new_pixbuf;
1017 *stream_size = size;
1023 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1025 ModestMsgEditWindowPrivate *priv;
1028 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1030 for (iter = tny_list_create_iterator (attachments);
1031 !tny_iterator_is_done (iter);
1032 tny_iterator_next (iter)) {
1033 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1034 const gchar *cid = tny_mime_part_get_content_id (part);
1035 const gchar *mime_type = tny_mime_part_get_content_type (part);
1036 if ((cid != NULL)&&(mime_type != NULL)) {
1037 guint64 stream_size;
1038 TnyStream *stream = tny_mime_part_get_decoded_stream (part);
1039 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
1042 g_object_unref (stream);
1044 if (pixbuf != NULL) {
1045 priv->images_count ++;
1046 priv->images_size += stream_size;
1047 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1048 g_object_unref (pixbuf);
1051 g_object_unref (part);
1053 g_object_unref (iter);
1057 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1059 TnyMimePart *parent = NULL;
1060 const gchar *content_type = NULL;
1061 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1063 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1065 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1066 parent = g_object_ref (msg);
1067 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1068 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1071 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1072 iter = tny_list_create_iterator (parts);
1073 while (!tny_iterator_is_done (iter)) {
1075 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1076 content_type = tny_mime_part_get_content_type (part);
1077 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1081 g_object_unref (part);
1083 tny_iterator_next (iter);
1085 g_object_unref (iter);
1086 g_object_unref (parts);
1089 if (parent != NULL) {
1090 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1093 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1094 iter = tny_list_create_iterator (parts);
1095 while (!tny_iterator_is_done (iter)) {
1097 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1098 content_type = tny_mime_part_get_content_type (part);
1099 if (content_type && g_str_has_prefix (content_type, "image/")) {
1100 tny_list_prepend (priv->images, (GObject *) part);
1102 g_object_unref (part);
1103 tny_iterator_next (iter);
1105 g_object_unref (iter);
1106 g_object_unref (parts);
1107 g_object_unref (parent);
1112 update_next_cid (ModestMsgEditWindow *self, TnyList *attachments)
1115 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1117 for (iter = tny_list_create_iterator (attachments) ;
1118 !tny_iterator_is_done (iter);
1119 tny_iterator_next (iter)) {
1120 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1121 const gchar *cid = tny_mime_part_get_content_id (part);
1123 char *invalid = NULL;
1124 gint int_cid = strtol (cid, &invalid, 10);
1125 if ((invalid != NULL) && (*invalid == '\0') && (int_cid >= priv->next_cid)) {
1126 priv->next_cid = int_cid + 1;
1129 g_object_unref (part);
1131 g_object_unref (iter);
1135 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1138 gchar *to, *cc, *bcc, *subject;
1140 ModestMsgEditWindowPrivate *priv;
1142 TnyHeaderFlags priority_flags;
1143 TnyFolder *msg_folder;
1144 gboolean is_html = FALSE;
1146 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1147 g_return_if_fail (TNY_IS_MSG (msg));
1149 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1151 header = tny_msg_get_header (msg);
1152 to = tny_header_dup_to (header);
1153 cc = tny_header_dup_cc (header);
1154 bcc = tny_header_dup_bcc (header);
1155 subject = tny_header_dup_subject (header);
1156 priority_flags = tny_header_get_priority (header);
1159 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1161 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1162 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1163 gtk_widget_show (priv->cc_caption);
1164 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1165 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1166 gtk_widget_hide (priv->cc_caption);
1169 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1170 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1171 gtk_widget_show (priv->bcc_caption);
1172 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1173 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1174 gtk_widget_hide (priv->bcc_caption);
1177 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1178 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1181 update_window_title (self);
1183 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1184 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1186 if ((body == NULL)||(body[0] == '\0')) {
1188 body = modest_text_utils_convert_to_html ("");
1191 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1192 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1195 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1198 /* Add attachments to the view */
1199 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1200 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1201 if (tny_list_get_length (priv->attachments) == 0) {
1202 gtk_widget_hide (priv->attachments_caption);
1204 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1205 gtk_widget_show_all (priv->attachments_caption);
1207 get_related_images (self, msg);
1208 update_next_cid (self, priv->attachments);
1209 update_next_cid (self, priv->images);
1210 replace_with_images (self, priv->images);
1212 if (preserve_is_rich && !is_html) {
1213 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1214 /* Get the default format required from configuration */
1215 } else if (!preserve_is_rich && !modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1216 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1219 /* Set the default focus depending on having already a To: field or not */
1220 if ((!to)||(*to == '\0')) {
1221 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1223 gtk_widget_grab_focus (priv->msg_body);
1226 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1228 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1229 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1231 modest_msg_edit_window_set_modified (self, FALSE);
1233 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1234 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1235 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1236 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1238 if (priv->msg_uid) {
1239 g_free (priv->msg_uid);
1240 priv->msg_uid = NULL;
1243 /* we should set a reference to the incoming message if it is a draft */
1244 msg_folder = tny_msg_get_folder (msg);
1246 if (modest_tny_folder_is_local_folder (msg_folder)) {
1247 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1248 if (type == TNY_FOLDER_TYPE_INVALID)
1249 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1251 if (type == TNY_FOLDER_TYPE_DRAFTS)
1252 priv->draft_msg = g_object_ref(msg);
1253 if (type == TNY_FOLDER_TYPE_OUTBOX)
1254 priv->outbox_msg = g_object_ref(msg);
1255 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1257 g_object_unref (msg_folder);
1267 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
1270 GList *item_children, *node;
1271 GtkWidget *bin_child;
1273 bin_child = gtk_bin_get_child (GTK_BIN(item));
1275 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
1277 for (node = item_children; node != NULL; node = g_list_next (node)) {
1278 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
1279 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
1282 g_list_free (item_children);
1286 menu_tool_button_dont_expand (GtkMenuToolButton *item)
1289 GList *item_children, *node;
1291 box = gtk_bin_get_child (GTK_BIN (item));
1292 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
1293 item_children = gtk_container_get_children (GTK_CONTAINER (box));
1295 for (node = item_children; node != NULL; node = g_list_next (node)) {
1296 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
1297 if (GTK_IS_TOGGLE_BUTTON (node->data))
1298 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
1299 else if (GTK_IS_BUTTON (node->data))
1300 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
1302 g_list_free (item_children);
1307 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1309 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1310 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1311 GtkWidget *placeholder;
1312 GtkWidget *tool_item;
1317 GtkWidget *sizes_menu;
1318 GtkWidget *fonts_menu;
1319 GSList *radio_group = NULL;
1320 GSList *node = NULL;
1324 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1325 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1327 /* Font color placeholder */
1328 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1329 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1332 tool_item = GTK_WIDGET (gtk_tool_item_new ());
1333 priv->font_color_button = hildon_color_button_new ();
1334 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
1335 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1336 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
1337 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1338 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1339 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1340 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1342 G_CALLBACK (modest_msg_edit_window_color_button_change),
1345 /* Font size and face placeholder */
1346 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1347 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1349 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1350 priv->size_tool_button_label = gtk_label_new (NULL);
1351 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1352 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1353 size_text,"</span>", NULL);
1354 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1356 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
1357 sizes_menu = gtk_menu_new ();
1358 priv->size_items_group = NULL;
1360 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1361 GtkWidget *size_menu_item;
1363 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1364 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
1365 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
1366 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
1367 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
1368 gtk_widget_show (size_menu_item);
1370 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
1374 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1375 GtkWidget *item = (GtkWidget *) node->data;
1376 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
1380 priv->size_items_group = g_slist_reverse (priv->size_items_group);
1381 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
1382 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1383 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1384 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1385 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1386 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1387 priv->font_size_toolitem = tool_item;
1390 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1391 priv->font_tool_button_label = gtk_label_new (NULL);
1392 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1393 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1395 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
1396 fonts_menu = gtk_menu_new ();
1397 priv->font_items_group = NULL;
1399 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1400 GtkWidget *font_menu_item;
1401 GtkWidget *child_label;
1403 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
1404 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
1405 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
1406 wp_get_font_name (font_index), "</span>", NULL);
1407 gtk_label_set_markup (GTK_LABEL (child_label), markup);
1410 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
1411 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
1412 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
1413 gtk_widget_show (font_menu_item);
1415 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
1418 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1419 GtkWidget *item = (GtkWidget *) node->data;
1420 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
1423 priv->font_items_group = g_slist_reverse (priv->font_items_group);
1424 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
1425 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1426 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1427 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1428 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1429 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1430 priv->font_face_toolitem = tool_item;
1432 /* Set expand and homogeneous for remaining items */
1433 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1434 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1435 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1436 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1437 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1438 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1439 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1440 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1441 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1443 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1444 will not show the tool items added to the placeholders) */
1445 gtk_widget_show_all (parent_priv->toolbar);
1447 /* Set the no show all *after* showing all items. We do not
1448 want the toolbar to be shown with a show all because it
1449 could go agains the gconf setting regarding showing or not
1450 the toolbar of the editor window */
1451 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1457 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean preserve_is_rich)
1460 ModestWindowPrivate *parent_priv;
1461 ModestMsgEditWindowPrivate *priv;
1462 ModestDimmingRulesGroup *menu_rules_group = NULL;
1463 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1464 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1465 ModestWindowMgr *mgr = NULL;
1467 g_return_val_if_fail (msg, NULL);
1468 g_return_val_if_fail (account_name, NULL);
1470 mgr = modest_runtime_get_window_mgr ();
1472 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1474 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1475 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1477 /* Menubar. Update the state of some toggles */
1478 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1479 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
1480 priv->from_field_protos = get_transports ();
1481 modest_selector_picker_set_pair_list (MODEST_SELECTOR_PICKER (priv->from_field), priv->from_field_protos);
1482 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1483 hildon_button_set_title (HILDON_BUTTON (priv->from_field),
1485 hildon_button_set_value (HILDON_BUTTON (priv->from_field),
1486 hildon_touch_selector_get_current_text
1487 (HILDON_TOUCH_SELECTOR (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (priv->from_field)))));
1488 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1489 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1492 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1494 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1496 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1498 priv->original_account_name = (account_name) ? g_strdup (account_name) : NULL;
1500 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new ();
1501 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1502 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1503 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1504 /* Add common dimming rules */
1505 modest_dimming_rules_group_add_rules (menu_rules_group,
1506 modest_msg_edit_window_menu_dimming_entries,
1507 G_N_ELEMENTS (modest_msg_edit_window_menu_dimming_entries),
1508 MODEST_WINDOW (obj));
1509 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1510 modest_msg_edit_window_toolbar_dimming_entries,
1511 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1512 MODEST_WINDOW (obj));
1513 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_button,
1514 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1515 MODEST_WINDOW (obj));
1516 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1517 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1518 MODEST_WINDOW (obj));
1519 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1520 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1521 MODEST_WINDOW (obj));
1522 /* Insert dimming rules group for this window */
1523 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1524 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1525 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1526 /* Checks the dimming rules */
1527 g_object_unref (menu_rules_group);
1528 g_object_unref (toolbar_rules_group);
1529 g_object_unref (clipboard_rules_group);
1530 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1532 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1534 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1535 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1536 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1537 priv->update_caption_visibility = TRUE;
1539 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1541 /* Track account-removed signal, this window should be closed
1542 in the case we're creating a mail associated to the account
1544 priv->account_removed_handler_id =
1545 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1547 G_CALLBACK(on_account_removed),
1550 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (MODEST_MSG_EDIT_WINDOW (obj));
1552 return (ModestWindow*) obj;
1556 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1558 GString **string_buffer = (GString **) user_data;
1560 *string_buffer = g_string_append (*string_buffer, buffer);
1566 * @result: A new string which should be freed with g_free().
1569 get_formatted_data (ModestMsgEditWindow *edit_window)
1571 ModestMsgEditWindowPrivate *priv;
1572 GString *string_buffer = g_string_new ("");
1574 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1576 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1578 modest_text_utils_hyperlinkify (string_buffer);
1580 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1582 return g_string_free (string_buffer, FALSE);
1587 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1590 const gchar *account_name;
1591 ModestMsgEditWindowPrivate *priv;
1592 TnyIterator *att_iter;
1594 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1596 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1598 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1599 g_return_val_if_fail (account_name, NULL);
1602 /* don't free these (except from) */
1603 data = g_slice_new0 (MsgData);
1604 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1606 data->account_name = g_strdup (account_name);
1607 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1608 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1609 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1610 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1611 if (priv->draft_msg) {
1612 data->draft_msg = g_object_ref (priv->draft_msg);
1613 } else if (priv->outbox_msg) {
1614 data->draft_msg = g_object_ref (priv->outbox_msg);
1616 data->draft_msg = NULL;
1619 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1621 gtk_text_buffer_get_bounds (buf, &b, &e);
1622 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1624 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1625 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1627 data->html_body = NULL;
1629 /* deep-copy the data */
1630 att_iter = tny_list_create_iterator (priv->attachments);
1631 data->attachments = NULL;
1632 while (!tny_iterator_is_done (att_iter)) {
1633 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1634 if (!(TNY_IS_MIME_PART(part))) {
1635 g_warning ("strange data in attachment list");
1636 g_object_unref (part);
1637 tny_iterator_next (att_iter);
1640 data->attachments = g_list_append (data->attachments,
1642 tny_iterator_next (att_iter);
1644 g_object_unref (att_iter);
1646 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1647 att_iter = tny_list_create_iterator (priv->images);
1648 data->images = NULL;
1649 while (!tny_iterator_is_done (att_iter)) {
1650 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1652 if (!(TNY_IS_MIME_PART(part))) {
1653 g_warning ("strange data in attachment list");
1654 g_object_unref (part);
1655 tny_iterator_next (att_iter);
1658 cid = tny_mime_part_get_content_id (part);
1660 gchar *image_tag_id;
1661 GtkTextTag *image_tag;
1663 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1664 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1665 g_free (image_tag_id);
1667 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1669 ((gtk_text_iter_has_tag (&iter, image_tag))||
1670 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1671 data->images = g_list_append (data->images,
1672 g_object_ref (part));
1674 g_object_unref (part);
1675 tny_iterator_next (att_iter);
1677 g_object_unref (att_iter);
1679 data->priority_flags = priv->priority_flags;
1686 unref_gobject (GObject *obj, gpointer data)
1688 if (!G_IS_OBJECT(obj))
1690 g_object_unref (obj);
1694 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1697 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1705 g_free (data->from);
1706 g_free (data->subject);
1707 g_free (data->plain_body);
1708 g_free (data->html_body);
1709 g_free (data->account_name);
1711 if (data->draft_msg != NULL) {
1712 g_object_unref (data->draft_msg);
1713 data->draft_msg = NULL;
1716 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1717 g_list_free (data->attachments);
1718 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1719 g_list_free (data->images);
1721 g_slice_free (MsgData, data);
1725 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1727 guint64 *parts_size)
1729 ModestMsgEditWindowPrivate *priv;
1731 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1733 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1735 /* TODO: add images */
1736 *parts_size += priv->images_size;
1737 *parts_count += priv->images_count;
1742 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1745 ModestMsgEditWindowPrivate *priv = NULL;
1746 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1748 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1750 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1752 return MODEST_MSG_EDIT_FORMAT_HTML;
1754 return MODEST_MSG_EDIT_FORMAT_TEXT;
1758 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1759 ModestMsgEditFormat format)
1761 ModestMsgEditWindowPrivate *priv;
1763 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1764 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1767 case MODEST_MSG_EDIT_FORMAT_HTML:
1768 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1770 case MODEST_MSG_EDIT_FORMAT_TEXT:
1771 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1774 g_return_if_reached ();
1778 ModestMsgEditFormatState *
1779 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1781 ModestMsgEditFormatState *format_state = NULL;
1782 ModestMsgEditWindowPrivate *priv;
1783 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1785 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1786 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1788 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1790 format_state = g_new0 (ModestMsgEditFormatState, 1);
1791 format_state->bold = buffer_format->bold&0x1;
1792 format_state->italics = buffer_format->italic&0x1;
1793 format_state->bullet = buffer_format->bullet&0x1;
1794 format_state->color = buffer_format->color;
1795 format_state->font_size = buffer_format->font_size;
1796 format_state->font_family = wp_get_font_name (buffer_format->font);
1797 format_state->justification = buffer_format->justification;
1798 g_free (buffer_format);
1800 return format_state;
1805 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1806 const ModestMsgEditFormatState *format_state)
1808 ModestMsgEditWindowPrivate *priv;
1809 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1810 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1811 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1812 g_return_if_fail (format_state != NULL);
1814 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1815 gtk_widget_grab_focus (priv->msg_body);
1816 buffer_format->bold = (format_state->bold != FALSE);
1817 buffer_format->italic = (format_state->italics != FALSE);
1818 buffer_format->color = format_state->color;
1819 buffer_format->font_size = format_state->font_size;
1820 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1821 buffer_format->justification = format_state->justification;
1822 buffer_format->bullet = format_state->bullet;
1824 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1826 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1827 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1828 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1829 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1830 buffer_format->cs.font = (buffer_format->font != current_format->font);
1831 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1832 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1834 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1835 if (buffer_format->cs.bold) {
1836 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1837 GINT_TO_POINTER (buffer_format->bold&0x1));
1839 if (buffer_format->cs.italic) {
1840 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1841 GINT_TO_POINTER (buffer_format->italic&0x1));
1843 if (buffer_format->cs.color) {
1844 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1845 GINT_TO_POINTER (&(buffer_format->color)));
1847 if (buffer_format->cs.font_size) {
1848 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1849 GINT_TO_POINTER (buffer_format->font_size));
1851 if (buffer_format->cs.justification) {
1852 switch (buffer_format->justification) {
1853 case GTK_JUSTIFY_LEFT:
1854 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1855 GINT_TO_POINTER(TRUE));
1857 case GTK_JUSTIFY_CENTER:
1858 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1859 GINT_TO_POINTER(TRUE));
1861 case GTK_JUSTIFY_RIGHT:
1862 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1863 GINT_TO_POINTER(TRUE));
1870 if (buffer_format->cs.font) {
1871 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1872 GINT_TO_POINTER (buffer_format->font));
1874 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1875 if (buffer_format->cs.bullet) {
1876 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
1877 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
1879 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1881 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
1883 g_free (buffer_format);
1884 g_free (current_format);
1886 /* Check dimming rules */
1887 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1888 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1892 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1894 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1896 ModestWindowPrivate *parent_priv;
1897 ModestMsgEditWindowPrivate *priv;
1898 GtkWidget *new_size_menuitem;
1899 GtkWidget *new_font_menuitem;
1901 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1902 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1904 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1905 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu");
1906 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1907 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1909 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatPlainTextMenu");
1910 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1911 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1914 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1916 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1917 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1919 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1920 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1922 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
1923 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
1926 switch (buffer_format->justification)
1928 case GTK_JUSTIFY_LEFT:
1929 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1931 case GTK_JUSTIFY_CENTER:
1932 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1934 case GTK_JUSTIFY_RIGHT:
1935 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1942 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1944 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1945 G_CALLBACK (modest_msg_edit_window_color_button_change),
1947 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1948 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1949 G_CALLBACK (modest_msg_edit_window_color_button_change),
1952 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1953 buffer_format->font_size))->data);
1954 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1958 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1959 markup = g_strconcat ("<span font_family='Sans'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1960 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1962 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1963 G_CALLBACK (modest_msg_edit_window_size_change),
1965 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1966 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1967 G_CALLBACK (modest_msg_edit_window_size_change),
1971 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1972 buffer_format->font))->data);
1973 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1977 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1978 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1979 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1981 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1982 G_CALLBACK (modest_msg_edit_window_font_change),
1984 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1985 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1986 G_CALLBACK (modest_msg_edit_window_font_change),
1990 g_free (buffer_format);
1994 #ifdef MODEST_HILDON_VERSION_0
1996 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1999 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2000 ModestMsgEditWindowPrivate *priv;
2001 GtkWidget *dialog = NULL;
2003 GdkColor *new_color = NULL;
2005 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2006 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2008 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2009 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2010 g_free (buffer_format);
2012 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2013 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2014 if (new_color != NULL) {
2015 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2016 (gpointer) new_color);
2019 gtk_widget_destroy (dialog);
2024 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2027 ModestMsgEditWindowPrivate *priv;
2028 GtkWidget *dialog = NULL;
2030 GdkColor *old_color = NULL;
2031 const GdkColor *new_color = NULL;
2033 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2034 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2036 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2037 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2039 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2040 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2041 if (new_color != NULL)
2042 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2044 gtk_widget_destroy (dialog);
2050 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2053 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2054 ModestMsgEditWindowPrivate *priv;
2055 GtkWidget *dialog = NULL;
2057 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2058 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2060 dialog = hildon_color_chooser_new ();
2061 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2062 g_free (buffer_format);
2064 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2066 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2067 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2070 gtk_widget_destroy (dialog);
2075 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2078 ModestMsgEditWindowPrivate *priv;
2079 GtkWidget *dialog = NULL;
2080 GdkColor *old_color = NULL;
2082 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2083 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2085 dialog = hildon_color_chooser_new ();
2086 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2088 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2090 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2091 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2093 gtk_widget_destroy (dialog);
2096 #endif /*!MODEST_HILDON_VERSION_0*/
2101 create_stream_for_uri (const gchar* uri)
2106 TnyStream *result = NULL;
2108 GnomeVFSHandle *handle = NULL;
2109 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2110 if (test == GNOME_VFS_OK) {
2111 TnyStream *vfssstream = TNY_STREAM (tny_vfs_stream_new (handle));
2112 /* Streams over OBEX (Bluetooth) are not seekable but
2113 * we expect them to be (we might need to read them
2114 * several times). So if this is a Bluetooth URI just
2115 * read the whole file into memory (this is not a fast
2116 * protocol so we can assume that these files are not
2117 * going to be very big) */
2118 if ((g_ascii_strncasecmp (uri, "obex://", 7) == 0)||
2119 (g_ascii_strncasecmp (uri, "upnpav://", 9) == 0)) {
2120 TnyStream *memstream = tny_camel_mem_stream_new ();
2121 tny_stream_write_to_stream (vfssstream, memstream);
2122 g_object_unref (vfssstream);
2125 result = vfssstream;
2133 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2136 ModestMsgEditWindowPrivate *priv;
2137 GtkWidget *dialog = NULL;
2139 GSList *uris = NULL;
2140 GSList *uri_node = NULL;
2142 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2144 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2145 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2146 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2148 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2150 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2151 GTK_WINDOW (dialog), GTK_WINDOW (window));
2153 response = gtk_dialog_run (GTK_DIALOG (dialog));
2155 case GTK_RESPONSE_OK:
2156 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2161 gtk_widget_destroy (dialog);
2163 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2165 GnomeVFSHandle *handle = NULL;
2166 GnomeVFSResult result;
2167 GtkTextIter position;
2168 GtkTextMark *insert_mark;
2170 uri = (const gchar *) uri_node->data;
2171 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2172 if (result == GNOME_VFS_OK) {
2174 GnomeVFSFileInfo *info;
2175 gchar *filename, *basename, *escaped_filename;
2176 TnyMimePart *mime_part;
2178 const gchar *mime_type = NULL;
2179 GnomeVFSURI *vfs_uri;
2180 guint64 stream_size;
2182 gnome_vfs_close (handle);
2183 vfs_uri = gnome_vfs_uri_new (uri);
2185 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2186 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2187 g_free (escaped_filename);
2188 gnome_vfs_uri_unref (vfs_uri);
2189 info = gnome_vfs_file_info_new ();
2191 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2192 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2194 mime_type = gnome_vfs_file_info_get_mime_type (info);
2196 mime_part = tny_platform_factory_new_mime_part
2197 (modest_runtime_get_platform_factory ());
2199 TnyStream *stream = create_stream_for_uri (uri);
2201 if (stream == NULL) {
2203 modest_platform_information_banner (NULL, NULL, dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2205 g_object_unref (mime_part);
2206 gnome_vfs_file_info_unref (info);
2210 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2212 content_id = g_strdup_printf ("%d", priv->next_cid);
2213 tny_mime_part_set_content_id (mime_part, content_id);
2214 g_free (content_id);
2217 basename = g_path_get_basename (filename);
2218 tny_mime_part_set_filename (mime_part, basename);
2221 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
2223 if (pixbuf != NULL) {
2224 priv->images_size += stream_size;
2225 priv->images_count ++;
2226 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2227 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2228 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
2229 g_object_unref (pixbuf);
2232 tny_list_prepend (priv->images, (GObject *) mime_part);
2233 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2235 g_object_unref (mime_part);
2236 gnome_vfs_file_info_unref (info);
2245 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2247 GtkWidget *dialog = NULL;
2249 GSList *uris = NULL;
2251 GnomeVFSFileSize total_size, allowed_size;
2252 ModestMsgEditWindowPrivate *priv;
2256 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(window));
2258 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2260 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2263 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2264 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2265 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2266 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), GTK_WINDOW (window));
2268 response = gtk_dialog_run (GTK_DIALOG (dialog));
2270 case GTK_RESPONSE_OK:
2271 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2276 gtk_widget_destroy (dialog);
2278 /* allowed size is the maximum size - what's already there */
2279 modest_attachments_view_get_sizes (
2280 MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2281 &att_num, &att_size);
2282 allowed_size = MODEST_MAX_ATTACHMENT_SIZE - att_size;
2285 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2287 const gchar *uri = (const gchar *) uri_node->data;
2289 total_size += modest_msg_edit_window_attach_file_one
2290 (window, uri, allowed_size);
2292 if (total_size > allowed_size) {
2293 g_warning ("%s: total size: %u",
2294 __FUNCTION__, (unsigned int)total_size);
2298 allowed_size -= total_size;
2302 g_slist_foreach (uris, (GFunc) g_free, NULL);
2303 g_slist_free (uris);
2308 modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window,
2310 GnomeVFSFileSize allowed_size)
2313 GnomeVFSHandle *handle = NULL;
2314 ModestMsgEditWindowPrivate *priv;
2315 GnomeVFSResult result;
2316 GnomeVFSFileSize size = 0;
2317 g_return_val_if_fail (window, 0);
2318 g_return_val_if_fail (uri, 0);
2320 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2322 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2323 if (result == GNOME_VFS_OK) {
2324 TnyMimePart *mime_part;
2326 const gchar *mime_type = NULL;
2328 gchar *escaped_filename;
2331 GnomeVFSFileInfo *info;
2332 GnomeVFSURI *vfs_uri;
2334 gnome_vfs_close (handle);
2335 vfs_uri = gnome_vfs_uri_new (uri);
2338 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2339 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2340 g_free (escaped_filename);
2341 gnome_vfs_uri_unref (vfs_uri);
2343 info = gnome_vfs_file_info_new ();
2345 if (gnome_vfs_get_file_info (uri,
2347 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2349 mime_type = gnome_vfs_file_info_get_mime_type (info);
2350 mime_part = tny_platform_factory_new_mime_part
2351 (modest_runtime_get_platform_factory ());
2353 /* try to get the attachment's size; this may fail for weird
2354 * file systems, like obex, upnp... */
2355 if (allowed_size != 0 &&
2356 info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
2358 if (size > allowed_size) {
2359 modest_platform_information_banner (NULL, NULL,
2360 dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2364 g_warning ("%s: could not get attachment size", __FUNCTION__);
2366 stream = create_stream_for_uri (uri);
2368 if (stream == NULL) {
2370 modest_platform_information_banner (NULL, NULL, dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2372 g_object_unref (mime_part);
2373 gnome_vfs_file_info_unref (info);
2377 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2378 g_object_unref (stream);
2380 content_id = g_strdup_printf ("%d", priv->next_cid);
2381 tny_mime_part_set_content_id (mime_part, content_id);
2382 g_free (content_id);
2385 basename = g_path_get_basename (filename);
2386 tny_mime_part_set_filename (mime_part, basename);
2389 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2390 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2392 info->size == 0, info->size);
2393 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2394 gtk_widget_show_all (priv->attachments_caption);
2395 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2397 g_object_unref (mime_part);
2398 gnome_vfs_file_info_unref (info);
2405 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2408 ModestMsgEditWindowPrivate *priv;
2411 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2412 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2414 if (att_list == NULL) {
2415 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2417 g_object_ref (att_list);
2420 if (tny_list_get_length (att_list) == 0) {
2421 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2423 gboolean dialog_response;
2424 gchar *message = NULL;
2425 gchar *filename = NULL;
2427 if (tny_list_get_length (att_list) == 1) {
2429 iter = tny_list_create_iterator (att_list);
2430 part = (TnyMimePart *) tny_iterator_get_current (iter);
2431 g_object_unref (iter);
2432 if (TNY_IS_MSG (part)) {
2433 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2435 filename = tny_header_dup_subject (header);
2436 g_object_unref (header);
2438 if (filename == NULL) {
2439 filename = g_strdup (_("mail_va_no_subject"));
2442 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2444 g_object_unref (part);
2446 filename = g_strdup ("");
2448 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
2449 tny_list_get_length (att_list)), filename);
2452 dialog_response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window), message);
2455 if (dialog_response != GTK_RESPONSE_OK) {
2456 g_object_unref (att_list);
2459 hildon_banner_show_information (NULL, NULL, _("mcen_me_inbox_remove_attachments"));
2461 for (iter = tny_list_create_iterator (att_list);
2462 !tny_iterator_is_done (iter);
2463 tny_iterator_next (iter)) {
2464 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2465 const gchar *att_id;
2466 tny_list_remove (priv->attachments, (GObject *) mime_part);
2468 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2470 if (tny_list_get_length (priv->attachments) == 0)
2471 gtk_widget_hide (priv->attachments_caption);
2472 att_id = tny_mime_part_get_content_id (mime_part);
2474 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2476 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2477 g_object_unref (mime_part);
2479 g_object_unref (iter);
2482 g_object_unref (att_list);
2484 /* if the last attachment has been removed, focus the Subject: field */
2485 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2486 gtk_widget_grab_focus (priv->subject_field);
2490 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2493 ModestMsgEditWindowPrivate *priv;
2494 GdkColor *new_color;
2495 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2497 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2498 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2501 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2503 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2505 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2507 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2512 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
2515 ModestMsgEditWindowPrivate *priv;
2516 gint new_size_index;
2517 ModestMsgEditWindow *window;
2520 window = MODEST_MSG_EDIT_WINDOW (userdata);
2521 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2522 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2524 if (gtk_check_menu_item_get_active (menu_item)) {
2526 WPTextBufferFormat format;
2528 memset (&format, 0, sizeof (format));
2529 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2531 label = gtk_bin_get_child (GTK_BIN (menu_item));
2533 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
2534 format.cs.font_size = TRUE;
2535 format.cs.text_position = TRUE;
2536 format.cs.font = TRUE;
2537 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
2538 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2540 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2541 GINT_TO_POINTER (wp_get_font_size_index (new_size_index, 12))))
2542 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2544 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2545 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
2546 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2552 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
2555 ModestMsgEditWindowPrivate *priv;
2556 gint new_font_index;
2557 ModestMsgEditWindow *window;
2560 window = MODEST_MSG_EDIT_WINDOW (userdata);
2561 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2562 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2564 if (gtk_check_menu_item_get_active (menu_item)) {
2567 label = gtk_bin_get_child (GTK_BIN (menu_item));
2569 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
2571 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2572 GINT_TO_POINTER(new_font_index)))
2573 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2575 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2576 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2577 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2583 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2586 ModestMsgEditWindowPrivate *priv = NULL;
2587 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2589 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2590 if (!priv->update_caption_visibility)
2593 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2595 gtk_widget_show (priv->cc_caption);
2597 gtk_widget_hide (priv->cc_caption);
2599 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2603 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2606 ModestMsgEditWindowPrivate *priv = NULL;
2607 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2609 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2610 if (!priv->update_caption_visibility)
2613 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2615 gtk_widget_show (priv->bcc_caption);
2617 gtk_widget_hide (priv->bcc_caption);
2619 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2623 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2624 ModestRecptEditor *editor)
2626 ModestMsgEditWindowPrivate *priv;
2628 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2629 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2631 /* we check for low-mem; in that case, show a warning, and don't allow
2632 * for the addressbook
2634 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2637 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2639 if (editor == NULL) {
2640 GtkWidget *view_focus;
2641 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2643 /* This code should be kept in sync with ModestRecptEditor. The
2644 textview inside the recpt editor is the one that really gets the
2645 focus. As it's inside a scrolled window, and this one inside the
2646 hbox recpt editor inherits from, we'll need to go up in the
2647 hierarchy to know if the text view is part of the recpt editor
2648 or if it's a different text entry */
2650 if (gtk_widget_get_parent (view_focus)) {
2651 GtkWidget *first_parent;
2653 first_parent = gtk_widget_get_parent (view_focus);
2654 if (gtk_widget_get_parent (first_parent) &&
2655 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2656 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2661 editor = MODEST_RECPT_EDITOR (priv->to_field);
2665 modest_address_book_select_addresses (editor);
2670 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2672 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2674 modest_msg_edit_window_open_addressbook (window, NULL);
2678 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2679 gboolean show_toolbar)
2681 ModestWindowPrivate *parent_priv;
2683 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2684 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2686 /* We can not just use the code of
2687 modest_msg_edit_window_setup_toolbar because it has a
2688 mixture of both initialization and creation code. */
2690 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2692 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2696 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2697 TnyHeaderFlags priority_flags)
2699 ModestMsgEditWindowPrivate *priv;
2700 ModestWindowPrivate *parent_priv;
2702 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2704 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2705 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2707 if (priv->priority_flags != priority_flags) {
2708 GtkAction *priority_action = NULL;
2710 priv->priority_flags = priority_flags;
2712 switch (priority_flags) {
2713 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2714 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2715 MODEST_HEADER_ICON_HIGH,
2716 HILDON_ICON_SIZE_XSMALL);
2717 gtk_widget_show (priv->priority_icon);
2718 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2719 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2721 case TNY_HEADER_FLAG_LOW_PRIORITY:
2722 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2723 MODEST_HEADER_ICON_LOW,
2724 HILDON_ICON_SIZE_XSMALL);
2725 gtk_widget_show (priv->priority_icon);
2726 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2727 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2730 gtk_widget_hide (priv->priority_icon);
2731 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2732 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2735 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2736 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2741 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2744 ModestMsgEditWindowPrivate *priv;
2745 ModestWindowPrivate *parent_priv;
2746 gint current_format;
2748 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2750 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2751 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2753 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2754 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2756 if (current_format != file_format) {
2757 switch (file_format) {
2758 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2759 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2760 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
2762 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2766 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2767 response = gtk_dialog_run (GTK_DIALOG (dialog));
2768 gtk_widget_destroy (dialog);
2769 if (response == GTK_RESPONSE_OK) {
2770 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2772 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu"));
2773 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
2778 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2779 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2780 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2785 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2788 ModestMsgEditWindowPrivate *priv;
2789 WPTextBufferFormat oldfmt, fmt;
2790 gint old_position = 0;
2794 GdkColor *color = NULL;
2795 gboolean bold, bold_set, italic, italic_set;
2796 gboolean underline, underline_set;
2797 gboolean strikethrough, strikethrough_set;
2798 gboolean position_set;
2799 gboolean font_size_set, font_set, color_set;
2802 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2803 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2805 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2806 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(),
2807 GTK_WINDOW(dialog), GTK_WINDOW (window));
2809 /* First we get the currently selected font information */
2810 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2812 switch (oldfmt.text_position) {
2813 case TEXT_POSITION_NORMAL:
2816 case TEXT_POSITION_SUPERSCRIPT:
2824 g_object_set (G_OBJECT (dialog),
2825 "bold", oldfmt.bold != FALSE,
2826 "bold-set", !oldfmt.cs.bold,
2827 "underline", oldfmt.underline != FALSE,
2828 "underline-set", !oldfmt.cs.underline,
2829 "italic", oldfmt.italic != FALSE,
2830 "italic-set", !oldfmt.cs.italic,
2831 "strikethrough", oldfmt.strikethrough != FALSE,
2832 "strikethrough-set", !oldfmt.cs.strikethrough,
2833 "color", &oldfmt.color,
2834 "color-set", !oldfmt.cs.color,
2835 "size", wp_font_size[oldfmt.font_size],
2836 "size-set", !oldfmt.cs.font_size,
2837 "position", old_position,
2838 "position-set", !oldfmt.cs.text_position,
2839 "family", wp_get_font_name (oldfmt.font),
2840 "family-set", !oldfmt.cs.font,
2843 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2844 GTK_WINDOW (dialog), GTK_WINDOW (window));
2845 gtk_widget_show_all (dialog);
2846 priv->font_dialog = dialog;
2847 response = gtk_dialog_run (GTK_DIALOG (dialog));
2848 priv->font_dialog = NULL;
2849 if (response == GTK_RESPONSE_OK) {
2851 g_object_get( dialog,
2853 "bold-set", &bold_set,
2854 "underline", &underline,
2855 "underline-set", &underline_set,
2857 "italic-set", &italic_set,
2858 "strikethrough", &strikethrough,
2859 "strikethrough-set", &strikethrough_set,
2861 "color-set", &color_set,
2863 "size-set", &font_size_set,
2864 "family", &font_name,
2865 "family-set", &font_set,
2866 "position", &position,
2867 "position-set", &position_set,
2872 if (response == GTK_RESPONSE_OK) {
2873 memset(&fmt, 0, sizeof(fmt));
2879 fmt.italic = italic;
2880 fmt.cs.italic = TRUE;
2882 if (underline_set) {
2883 fmt.underline = underline;
2884 fmt.cs.underline = TRUE;
2886 if (strikethrough_set) {
2887 fmt.strikethrough = strikethrough;
2888 fmt.cs.strikethrough = TRUE;
2893 ? TEXT_POSITION_NORMAL
2894 : ( ( position == 1 )
2895 ? TEXT_POSITION_SUPERSCRIPT
2896 : TEXT_POSITION_SUBSCRIPT );
2897 fmt.cs.text_position = TRUE;
2898 fmt.font_size = oldfmt.font_size;
2902 fmt.cs.color = TRUE;
2905 fmt.font = wp_get_font_index(font_name,
2910 if (font_size_set) {
2911 fmt.cs.font_size = TRUE;
2912 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
2914 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2915 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2917 gtk_widget_destroy (dialog);
2919 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2923 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2925 ModestMsgEditWindowPrivate *priv;
2927 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2928 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2930 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2932 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2933 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2937 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2939 ModestMsgEditWindowPrivate *priv;
2941 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2942 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2944 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2946 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2947 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2952 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2954 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2956 priv->can_undo = can_undo;
2960 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2962 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2964 priv->can_redo = can_redo;
2968 modest_msg_edit_window_can_undo (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_undo;
2978 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
2980 ModestMsgEditWindowPrivate *priv;
2981 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2982 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2984 return priv->can_redo;
2989 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2992 GtkTextIter match_start, match_end;
2994 if (image_id == NULL)
2997 gtk_text_buffer_get_start_iter (buffer, &iter);
2999 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
3000 GSList *tags = gtk_text_iter_get_tags (&match_start);
3002 for (node = tags; node != NULL; node = g_slist_next (node)) {
3003 GtkTextTag *tag = (GtkTextTag *) node->data;
3004 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
3005 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
3006 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
3008 offset = gtk_text_iter_get_offset (&match_start);
3009 gtk_text_buffer_delete (buffer, &match_start, &match_end);
3010 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
3014 gtk_text_iter_forward_char (&iter);
3019 message_is_empty (ModestMsgEditWindow *window)
3021 ModestMsgEditWindowPrivate *priv = NULL;
3023 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3024 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3026 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
3027 * so we can ignore markup.
3029 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
3032 count = gtk_text_buffer_get_char_count (buf);
3038 msg_body_focus (GtkWidget *focus,
3039 GdkEventFocus *event,
3043 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3044 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3045 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3050 recpt_field_changed (GtkTextBuffer *buffer,
3051 ModestMsgEditWindow *editor)
3053 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3054 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3058 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3060 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3061 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3065 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3068 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3069 GtkTextBuffer *buffer;
3071 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3072 gtk_text_buffer_set_modified (buffer, modified);
3073 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3074 gtk_text_buffer_set_modified (buffer, modified);
3075 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3076 gtk_text_buffer_set_modified (buffer, modified);
3077 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3081 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3083 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3084 const char *account_name;
3085 GtkTextBuffer *buffer;
3087 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3088 if (gtk_text_buffer_get_modified (buffer))
3090 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3091 if (gtk_text_buffer_get_modified (buffer))
3093 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3094 if (gtk_text_buffer_get_modified (buffer))
3096 if (gtk_text_buffer_get_modified (priv->text_buffer))
3098 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3099 if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3110 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3112 ModestMsgEditWindowPrivate *priv = NULL;
3114 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3115 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3117 /* check if there's no recipient added */
3118 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3119 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3120 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3121 /* no recipient contents, then select contacts */
3122 modest_msg_edit_window_open_addressbook (window, NULL);
3126 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3127 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3130 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3131 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3134 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3135 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3139 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3140 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3141 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3148 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3149 ModestMsgEditWindow *window)
3151 modest_msg_edit_window_offer_attach_file (window);
3155 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3157 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3159 return priv->clipboard_text;
3163 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3165 ModestMsgEditWindow *window)
3167 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3168 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3170 if (!GTK_WIDGET_VISIBLE (window))
3173 g_object_ref (window);
3174 text = gtk_clipboard_wait_for_text (selection_clipboard);
3176 if (priv->clipboard_text != NULL) {
3177 g_free (priv->clipboard_text);
3179 priv->clipboard_text = text;
3181 if (GTK_WIDGET_VISIBLE (window)) {
3182 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3184 g_object_unref (window);
3187 static gboolean clipboard_owner_change_idle (gpointer userdata)
3189 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
3190 ModestMsgEditWindowPrivate *priv;
3192 gdk_threads_enter ();
3193 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3194 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3196 priv->clipboard_owner_idle = 0;
3197 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, window);
3198 gdk_threads_leave ();
3204 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window)
3206 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3207 if (priv->clipboard_owner_idle == 0) {
3208 priv->clipboard_owner_idle = g_idle_add (clipboard_owner_change_idle, window);
3213 subject_field_move_cursor (GtkEntry *entry,
3214 GtkMovementStep step,
3219 if (!GTK_WIDGET_VISIBLE (window))
3222 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3226 update_window_title (ModestMsgEditWindow *window)
3228 ModestMsgEditWindowPrivate *priv = NULL;
3229 const gchar *subject;
3231 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3232 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3233 if (subject == NULL || subject[0] == '\0')
3234 subject = _("mail_va_new_email");
3236 gtk_window_set_title (GTK_WINDOW (window), subject);
3241 subject_field_changed (GtkEditable *editable,
3242 ModestMsgEditWindow *window)
3244 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3245 update_window_title (window);
3246 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3247 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3248 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3252 subject_field_insert_text (GtkEditable *editable,
3254 gint new_text_length,
3256 ModestMsgEditWindow *window)
3258 GString *result = g_string_new ("");
3260 gint result_len = 0;
3261 const gchar *entry_text = NULL;
3264 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3265 old_length = g_utf8_strlen (entry_text, -1);
3267 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3268 gunichar c = g_utf8_get_char_validated (current, 8);
3269 /* Invalid unichar, stop */
3275 result = g_string_append_unichar (result, c);
3279 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3280 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3283 /* Prevent endless recursion */
3284 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3285 g_signal_emit_by_name (editable, "insert-text",
3286 (gpointer) result->str, (gpointer) result->len,
3287 (gpointer) position, (gpointer) window);
3288 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3292 if (result_len + old_length > 1000) {
3293 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3294 dgettext("hildon-common-strings",
3295 "ckdg_ib_maximum_characters_reached"));
3298 g_string_free (result, TRUE);
3302 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3305 ModestMsgEditWindowPrivate *priv = NULL;
3307 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3308 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3310 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3313 gtk_widget_show_all (priv->find_toolbar);
3314 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3316 gtk_widget_hide_all (priv->find_toolbar);
3317 gtk_widget_grab_focus (priv->msg_body);
3323 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3325 GtkTextIter *match_start,
3326 GtkTextIter *match_end)
3328 GtkTextIter end_iter;
3329 gchar *str_casefold;
3332 gchar *range_casefold;
3335 gboolean result = FALSE;
3342 gtk_text_iter_forward_to_end (&end_iter);
3344 str_casefold = g_utf8_casefold (str, -1);
3345 str_chars_n = strlen (str);
3347 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3348 range_casefold = g_utf8_casefold (range_text, -1);
3349 range_chars_n = strlen (range_casefold);
3351 if (range_chars_n < str_chars_n) {
3352 g_free (str_casefold);
3353 g_free (range_text);
3354 g_free (range_casefold);
3358 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3359 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3360 if (!g_utf8_collate (range_subtext, str_casefold)) {
3361 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3363 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3364 match_start, match_end, NULL);
3365 g_free (found_text);
3367 g_free (range_subtext);
3371 g_free (str_casefold);
3372 g_free (range_text);
3373 g_free (range_casefold);
3380 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3381 ModestMsgEditWindow *window)
3383 gchar *current_search = NULL;
3384 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3386 GtkTextIter selection_start, selection_end;
3387 GtkTextIter match_start, match_end;
3388 gboolean continue_search = FALSE;
3390 if (message_is_empty (window)) {
3391 g_free (priv->last_search);
3392 priv->last_search = NULL;
3393 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3397 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3398 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3399 g_free (current_search);
3400 g_free (priv->last_search);
3401 priv->last_search = NULL;
3402 /* Information banner about empty search */
3403 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
3407 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3408 continue_search = TRUE;
3410 g_free (priv->last_search);
3411 priv->last_search = g_strdup (current_search);
3414 if (continue_search) {
3415 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3416 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3417 &match_start, &match_end);
3419 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
3421 GtkTextIter buffer_start;
3422 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3423 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3424 &match_start, &match_end);
3426 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
3429 /* Mark as selected the string found in search */
3431 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3432 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3433 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3435 g_free (priv->last_search);
3436 priv->last_search = NULL;
3438 g_free (current_search);
3442 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3443 ModestMsgEditWindow *window)
3445 GtkToggleAction *toggle;
3446 ModestWindowPrivate *parent_priv;
3447 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3449 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
3450 gtk_toggle_action_set_active (toggle, FALSE);
3454 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3456 ModestMsgEditWindowPrivate *priv;
3458 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3463 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3466 ModestMsgEditWindowPrivate *priv;
3468 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3474 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3477 ModestMsgEditWindowPrivate *priv;
3478 TnyHeader *header = NULL;
3480 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3481 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3483 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3484 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3486 if (priv->draft_msg != NULL) {
3487 g_object_unref (priv->draft_msg);
3490 if (draft != NULL) {
3491 g_object_ref (draft);
3492 header = tny_msg_get_header (draft);
3493 if (priv->msg_uid) {
3494 g_free (priv->msg_uid);
3495 priv->msg_uid = NULL;
3497 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3498 if (GTK_WIDGET_REALIZED (window)) {
3499 if (!modest_window_mgr_register_window (mgr, MODEST_WINDOW (window), NULL)) {
3500 gtk_widget_destroy (GTK_WIDGET (window));
3506 priv->draft_msg = draft;
3510 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3511 GtkTextIter *start, GtkTextIter *end,
3514 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3515 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3518 if (tag == NULL) return;
3519 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3520 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3521 replace_with_images (window, priv->images);
3526 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3529 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3531 g_return_if_fail (TNY_IS_MIME_PART (part));
3532 tny_list_prepend (priv->attachments, (GObject *) part);
3533 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3534 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3535 gtk_widget_show_all (priv->attachments_caption);
3536 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3540 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3542 ModestMsgEditWindowPrivate *priv;
3544 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3545 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3547 return priv->msg_uid;
3551 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3552 ModestMsgEditWindowWidgetType widget_type)
3554 ModestMsgEditWindowPrivate *priv;
3556 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3557 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3559 switch (widget_type) {
3560 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3561 return priv->msg_body;
3563 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3564 return priv->to_field;
3566 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3567 return priv->cc_field;
3569 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3570 return priv->bcc_field;
3572 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3573 return priv->subject_field;
3575 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3576 return priv->attachments_view;
3584 remove_tags (WPTextBuffer *buffer)
3586 GtkTextIter start, end;
3588 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3589 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3591 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3595 on_account_removed (TnyAccountStore *account_store,
3596 TnyAccount *account,
3599 /* Do nothing if it's a store account, because we use the
3600 transport to send the messages */
3601 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3602 const gchar *parent_acc = NULL;
3603 const gchar *our_acc = NULL;
3605 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3606 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3607 /* Close this window if I'm showing a message of the removed account */
3608 if (strcmp (parent_acc, our_acc) == 0)
3609 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3614 on_zoom_minus_plus_not_implemented (ModestWindow *window)
3616 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3618 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
3624 set_zoom_do_nothing (ModestWindow *window,
3630 get_zoom_do_nothing (ModestWindow *window)