1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37 #include <tny-vfs-stream.h>
41 #include <modest-account-mgr.h>
42 #include <modest-account-mgr-helpers.h>
44 #include <widgets/modest-msg-edit-window.h>
45 #include <widgets/modest-combo-box.h>
46 #include <widgets/modest-recpt-editor.h>
47 #include <widgets/modest-attachments-view.h>
49 #include <modest-runtime.h>
51 #include "modest-platform.h"
52 #include "modest-icon-names.h"
53 #include "modest-widget-memory.h"
54 #include "modest-window-priv.h"
55 #include "modest-mail-operation.h"
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-tny-folder.h"
59 #include "modest-tny-account.h"
60 #include "modest-address-book.h"
61 #include "modest-text-utils.h"
62 #include <tny-simple-list.h>
63 #include <wptextview.h>
64 #include <wptextbuffer.h>
65 #include "modest-scroll-area.h"
66 #include "modest-msg-edit-window-ui-dimming.h"
68 #include "modest-hildon-includes.h"
69 #ifdef MODEST_HAVE_HILDON0_WIDGETS
70 #include <hildon-widgets/hildon-color-chooser.h>
72 #include "widgets/modest-msg-edit-window-ui.h"
73 #ifdef MODEST_HAVE_HILDON0_WIDGETS
74 #include <libgnomevfs/gnome-vfs-mime-utils.h>
76 #include <libgnomevfs/gnome-vfs-mime.h>
78 #include <modest-utils.h>
79 #include "modest-maemo-utils.h"
82 #define DEFAULT_FONT_SIZE 3
83 #define DEFAULT_FONT 2
84 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
85 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
86 #define DEFAULT_MAIN_VBOX_SPACING 6
87 #define SUBJECT_MAX_LENGTH 1000
88 #define IMAGE_MAX_WIDTH 560
89 #define DEFAULT_FONT_SCALE 1.5
91 static gboolean is_wp_text_buffer_started = FALSE;
93 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
94 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
95 static void modest_msg_edit_window_finalize (GObject *obj);
97 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
98 static void body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
99 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
101 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
102 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
103 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
104 static void text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
105 GtkTextIter *start, GtkTextIter *end,
107 static void text_buffer_insert_text (GtkTextBuffer *buffer,
108 GtkTextIter *location,
111 ModestMsgEditWindow *window);
112 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
113 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
114 static void subject_field_insert_text (GtkEditable *editable,
116 gint new_text_length,
118 ModestMsgEditWindow *window);
119 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
121 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
123 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
125 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
126 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
127 GdkEventWindowState *event,
129 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
130 ModestRecptEditor *editor);
131 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
132 ModestMsgEditWindow *window);
134 /* ModestWindow methods implementation */
135 static void modest_msg_edit_window_disconnect_signals (ModestWindow *window);
136 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
137 gboolean show_toolbar);
138 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
140 ModestMsgEditWindow *window);
141 static void subject_field_move_cursor (GtkEntry *entry,
142 GtkMovementStep step,
146 static void update_window_title (ModestMsgEditWindow *window);
149 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
150 ModestMsgEditWindow *window);
151 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
152 ModestMsgEditWindow *window);
153 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
155 GtkTextIter *match_start,
156 GtkTextIter *match_end);
158 static void remove_tags (WPTextBuffer *buffer);
160 static void on_account_removed (TnyAccountStore *account_store,
164 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
165 static void set_zoom_do_nothing (ModestWindow *window, gdouble zoom);
166 static gdouble get_zoom_do_nothing (ModestWindow *window);
168 static void init_window (ModestMsgEditWindow *obj);
170 gboolean scroll_drag_timeout (gpointer userdata);
171 static void correct_scroll (ModestMsgEditWindow *w);
172 static void correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused);
173 static void text_buffer_end_user_action (GtkTextBuffer *buffer,
174 ModestMsgEditWindow *userdata);
175 static void text_buffer_mark_set (GtkTextBuffer *buffer,
178 ModestMsgEditWindow *userdata);
179 void vadj_changed (GtkAdjustment *adj,
180 ModestMsgEditWindow *window);
182 static ModestPair *find_transport_from_message_sender (ModestPairList *transports,
188 static void DEBUG_BUFFER (WPTextBuffer *buffer)
192 g_message ("BEGIN BUFFER OF SIZE %d", gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (buffer)));
194 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
195 while (!gtk_text_iter_is_end (&iter)) {
196 GString *output = g_string_new ("");
197 GSList *toggled_tags;
200 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
201 g_string_append_printf (output, "%d: CLOSED [ ", gtk_text_iter_get_offset (&iter));
202 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
203 GtkTextTag *tag = (GtkTextTag *) node->data;
205 g_object_get (G_OBJECT (tag), "name", &name, NULL);
206 output = g_string_append (output, name);
207 g_string_append (output, " ");
209 output = g_string_append (output, "] OPENED [ ");
210 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
211 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
212 GtkTextTag *tag = (GtkTextTag *) node->data;
214 g_object_get (G_OBJECT (tag), "name", &name, NULL);
215 output = g_string_append (output, name);
216 g_string_append (output, " ");
218 output = g_string_append (output, "]\n");
219 g_message ("%s", output->str);
220 g_string_free (output, TRUE);
221 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
223 g_message ("END BUFFER");
228 /* static gboolean */
229 /* on_key_pressed (GtkWidget *self, */
230 /* GdkEventKey *event, */
231 /* gpointer user_data); */
233 /* list my signals */
240 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
241 struct _ModestMsgEditWindowPrivate {
244 GtkWidget *header_box;
246 ModestPairList *from_field_protos;
247 GtkWidget *from_field;
248 const gchar *original_account_name;
252 GtkWidget *bcc_field;
253 GtkWidget *subject_field;
254 GtkWidget *attachments_view;
255 GtkWidget *priority_icon;
256 GtkWidget *add_attachment_button;
258 GtkWidget *cc_caption;
259 GtkWidget *bcc_caption;
260 gboolean update_caption_visibility;
261 GtkWidget *attachments_caption;
263 GtkTextBuffer *text_buffer;
265 GtkWidget *font_size_toolitem;
266 GtkWidget *font_face_toolitem;
267 GtkWidget *font_color_button;
268 GSList *font_items_group;
269 GtkWidget *font_tool_button_label;
270 GSList *size_items_group;
271 GtkWidget *size_tool_button_label;
273 GtkWidget *find_toolbar;
277 guint scroll_drag_timeout_id;
281 TnyList *attachments;
286 TnyHeaderFlags priority_flags;
288 gboolean can_undo, can_redo;
289 gulong clipboard_change_handler_id;
290 gulong default_clipboard_change_handler_id;
291 gulong account_removed_handler_id;
292 gchar *clipboard_text;
301 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
302 MODEST_TYPE_MSG_EDIT_WINDOW, \
303 ModestMsgEditWindowPrivate))
305 static GtkWindowClass *parent_class = NULL;
307 /* uncomment the following if you have defined any signals */
308 /* static guint signals[LAST_SIGNAL] = {0}; */
311 modest_msg_edit_window_get_type (void)
313 static GType my_type = 0;
315 static const GTypeInfo my_info = {
316 sizeof(ModestMsgEditWindowClass),
317 NULL, /* base init */
318 NULL, /* base finalize */
319 (GClassInitFunc) modest_msg_edit_window_class_init,
320 NULL, /* class finalize */
321 NULL, /* class data */
322 sizeof(ModestMsgEditWindow),
324 (GInstanceInitFunc) modest_msg_edit_window_init,
327 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
328 "ModestMsgEditWindow",
336 save_state (ModestWindow *self)
338 modest_widget_memory_save (modest_runtime_get_conf(),
339 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
344 restore_settings (ModestMsgEditWindow *self)
346 ModestConf *conf = NULL;
348 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
350 conf = modest_runtime_get_conf ();
351 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
352 "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarNormalScreenMenu");
353 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
354 modest_conf_get_bool (conf, MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR, NULL));
355 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
356 "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarFullScreenMenu");
357 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
358 modest_conf_get_bool (conf, MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
360 /* set initial state of cc and bcc */
361 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
362 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
363 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
364 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
365 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
366 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
368 /* Dim at start clipboard actions */
369 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
370 gtk_action_set_sensitive (action, FALSE);
371 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
372 gtk_action_set_sensitive (action, FALSE);
373 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
374 gtk_action_set_sensitive (action, FALSE);
376 modest_widget_memory_restore (conf,
377 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
382 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
384 GObjectClass *gobject_class;
385 ModestWindowClass *modest_window_class;
386 gobject_class = (GObjectClass*) klass;
387 modest_window_class = (ModestWindowClass*) klass;
389 parent_class = g_type_class_peek_parent (klass);
390 gobject_class->finalize = modest_msg_edit_window_finalize;
392 modest_window_class->set_zoom_func = set_zoom_do_nothing;
393 modest_window_class->get_zoom_func = get_zoom_do_nothing;
394 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
395 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
396 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
397 modest_window_class->save_state_func = save_state;
398 modest_window_class->disconnect_signals_func = modest_msg_edit_window_disconnect_signals;
400 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
404 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
406 ModestMsgEditWindowPrivate *priv;
407 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
409 priv->msg_body = NULL;
411 priv->from_field = NULL;
412 priv->to_field = NULL;
413 priv->cc_field = NULL;
414 priv->bcc_field = NULL;
415 priv->subject_field = NULL;
416 priv->attachments = TNY_LIST (tny_simple_list_new ());
417 priv->images = TNY_LIST (tny_simple_list_new ());
418 priv->images_size = 0;
419 priv->images_count = 0;
422 priv->cc_caption = NULL;
423 priv->bcc_caption = NULL;
424 priv->update_caption_visibility = FALSE;
426 priv->priority_flags = 0;
428 priv->find_toolbar = NULL;
429 priv->last_search = NULL;
431 priv->draft_msg = NULL;
432 priv->outbox_msg = NULL;
433 priv->msg_uid = NULL;
435 priv->can_undo = FALSE;
436 priv->can_redo = FALSE;
437 priv->clipboard_change_handler_id = 0;
438 priv->default_clipboard_change_handler_id = 0;
439 priv->account_removed_handler_id = 0;
440 priv->clipboard_text = NULL;
443 priv->scroll_drag_timeout_id = 0;
444 priv->last_upper = 0.0;
446 modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
447 GTK_WINDOW(obj),"applications_email_editor");
449 if (!is_wp_text_buffer_started) {
450 is_wp_text_buffer_started = TRUE;
451 wp_text_buffer_library_init ();
456 hildon_program_add_window (hildon_program_get_instance(),
461 /* FIXME: this is a dup from the one in gtk/ */
464 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
466 static ModestPairList*
467 get_transports (void)
469 GSList *transports = NULL;
471 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
472 GSList *accounts = modest_account_mgr_account_names (account_mgr,
473 TRUE /* only enabled accounts. */);
475 GSList *cursor = accounts;
477 gchar *account_name = cursor->data;
478 gchar *from_string = NULL;
480 from_string = modest_account_mgr_get_from_string (account_mgr,
484 if (from_string && account_name) {
485 gchar *name = account_name;
486 ModestPair *pair = modest_pair_new ((gpointer) name,
487 (gpointer) from_string , TRUE);
488 transports = g_slist_prepend (transports, pair);
491 cursor = cursor->next;
493 g_slist_free (accounts); /* only free the accounts, not the elements,
494 * because they are used in the pairlist */
499 * Search an (account, address) ModestPairList for a pair whose
500 * address matches the one in the From: header of a TnyMsg
502 * @result: A ModestPair * with a matching address, or NULL if none found
505 find_transport_from_message_sender (ModestPairList *transports, TnyMsg *msg)
507 g_return_val_if_fail (transports, NULL);
508 g_return_val_if_fail (msg, NULL);
510 ModestPair *account_pair = NULL;
511 TnyHeader *header = tny_msg_get_header (msg);
513 if (header != NULL && tny_header_get_from (header)) {
514 char *from_addr = modest_text_utils_get_email_address (tny_header_get_from (header));
516 for (iter = transports; iter && !account_pair; iter = iter->next) {
517 ModestPair *pair = (ModestPair *) iter->data;
518 char *account_addr = modest_text_utils_get_email_address ((char *) pair->second);
519 if (account_addr && !strcasecmp(from_addr, account_addr)) {
522 g_free (account_addr);
528 g_object_unref (header);
533 static void window_focus (GtkWindow *window,
537 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
541 scroll_drag_timeout (gpointer userdata)
543 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
544 ModestMsgEditWindowPrivate *priv;
546 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
548 correct_scroll_without_drag_check (win, TRUE);
550 priv->scroll_drag_timeout_id = 0;
556 correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused)
558 ModestMsgEditWindowPrivate *priv;
561 GdkRectangle rectangle;
567 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
569 if (only_if_focused && !gtk_widget_is_focus (priv->msg_body))
572 insert = gtk_text_buffer_get_insert (priv->text_buffer);
573 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
575 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
576 vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll));
577 offset = priv->msg_body->allocation.y;
579 new_value = vadj->value;
581 if ((offset + rectangle.y + rectangle.height) >
582 ((gint) (vadj->value +vadj->page_size))) {
583 new_value = (offset + rectangle.y) - vadj->page_size * 0.25;
584 if (new_value > vadj->upper - vadj->page_size)
585 new_value = vadj->upper - vadj->page_size;
586 } else if ((offset + rectangle.y) < ((gint) vadj->value)) {
587 new_value = (offset + rectangle.y - vadj->page_size * 0.75);
588 if (((gint) (new_value + vadj->page_size)) < (offset + rectangle.y + rectangle.height))
589 new_value = offset + rectangle.y + rectangle.height - (gint) vadj->page_size;
592 if (new_value > vadj->value)
593 new_value = vadj->value;
596 if (vadj->value != new_value) {
597 g_signal_emit_by_name (GTK_TEXT_VIEW(priv->msg_body)->layout,
599 vadj->value = new_value;
600 gtk_adjustment_value_changed (vadj);
601 /* invalidate body */
602 window = gtk_widget_get_parent_window (priv->msg_body);
604 gdk_window_invalidate_rect (window, NULL, TRUE);
610 correct_scroll (ModestMsgEditWindow *w)
612 ModestMsgEditWindowPrivate *priv;
614 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
615 if (gtk_grab_get_current () == priv->msg_body) {
616 if (priv->scroll_drag_timeout_id == 0) {
617 priv->scroll_drag_timeout_id = g_timeout_add (500, (GSourceFunc) scroll_drag_timeout,
623 correct_scroll_without_drag_check (w, TRUE);
627 text_buffer_end_user_action (GtkTextBuffer *buffer,
628 ModestMsgEditWindow *userdata)
631 correct_scroll (userdata);
635 text_buffer_mark_set (GtkTextBuffer *buffer,
638 ModestMsgEditWindow *userdata)
640 gtk_text_buffer_begin_user_action (buffer);
641 gtk_text_buffer_end_user_action (buffer);
645 cut_clipboard_check (GtkTextView *text_view,
648 GtkTextBuffer *buffer;
650 buffer = gtk_text_view_get_buffer (text_view);
651 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
652 g_signal_stop_emission_by_name ((gpointer )text_view, "cut-clipboard");
657 copy_clipboard_check (GtkTextView *text_view,
660 GtkTextBuffer *buffer;
662 buffer = gtk_text_view_get_buffer (text_view);
663 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
664 g_signal_stop_emission_by_name ((gpointer )text_view, "copy-clipboard");
668 void vadj_changed (GtkAdjustment *adj,
669 ModestMsgEditWindow *window)
671 ModestMsgEditWindowPrivate *priv;
673 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
675 if (priv->last_upper != adj->upper) {
676 priv->last_upper = adj->upper;
677 correct_scroll (window);
682 connect_signals (ModestMsgEditWindow *obj)
684 ModestMsgEditWindowPrivate *priv;
686 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
688 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
689 G_CALLBACK (text_buffer_refresh_attributes), obj);
690 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
691 G_CALLBACK (text_buffer_can_undo), obj);
692 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
693 G_CALLBACK (text_buffer_can_redo), obj);
694 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
695 G_CALLBACK (body_changed), obj);
696 g_signal_connect (G_OBJECT (priv->text_buffer), "insert-text",
697 G_CALLBACK (text_buffer_insert_text), obj);
698 g_signal_connect (G_OBJECT (obj), "window-state-event",
699 G_CALLBACK (modest_msg_edit_window_window_state_event),
701 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
702 G_CALLBACK (text_buffer_end_user_action), obj);
703 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
704 G_CALLBACK (text_buffer_mark_set), obj);
705 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
706 G_CALLBACK (text_buffer_apply_tag), obj);
707 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
708 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
709 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
710 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
711 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
712 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
714 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
715 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
717 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
718 G_CALLBACK (msg_body_focus), obj);
719 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
720 G_CALLBACK (msg_body_focus), obj);
721 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
722 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
723 "changed", G_CALLBACK (recpt_field_changed), obj);
724 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
725 "changed", G_CALLBACK (recpt_field_changed), obj);
726 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
727 "changed", G_CALLBACK (recpt_field_changed), obj);
728 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
729 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
730 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
732 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
733 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
735 g_signal_connect (G_OBJECT (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll))),
737 G_CALLBACK (vadj_changed),
740 priv->clipboard_change_handler_id =
741 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
742 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
743 priv->default_clipboard_change_handler_id =
744 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
745 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
747 g_signal_connect (G_OBJECT (priv->msg_body), "cut-clipboard", G_CALLBACK (cut_clipboard_check), NULL);
748 g_signal_connect (G_OBJECT (priv->msg_body), "copy-clipboard", G_CALLBACK (copy_clipboard_check), NULL);
753 init_window (ModestMsgEditWindow *obj)
755 GtkWidget *from_caption, *to_caption, *subject_caption;
756 GtkWidget *main_vbox;
757 ModestMsgEditWindowPrivate *priv;
758 GtkActionGroup *action_group;
759 ModestWindowPrivate *parent_priv;
760 GdkPixbuf *window_icon = NULL;
761 GError *error = NULL;
763 GtkSizeGroup *size_group;
764 GtkWidget *subject_box;
765 GtkWidget *attachment_icon;
766 GtkWidget *window_box;
767 #if (GTK_MINOR_VERSION >= 10)
768 GdkAtom deserialize_type;
770 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
771 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
773 parent_priv->ui_manager = gtk_ui_manager_new();
774 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
775 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
777 /* Add common actions */
778 gtk_action_group_add_actions (action_group,
779 modest_msg_edit_action_entries,
780 G_N_ELEMENTS (modest_msg_edit_action_entries),
782 gtk_action_group_add_toggle_actions (action_group,
783 modest_msg_edit_toggle_action_entries,
784 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
786 gtk_action_group_add_radio_actions (action_group,
787 modest_msg_edit_alignment_radio_action_entries,
788 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
790 G_CALLBACK (modest_ui_actions_on_change_justify),
792 gtk_action_group_add_radio_actions (action_group,
793 modest_msg_edit_priority_action_entries,
794 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
796 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
798 gtk_action_group_add_radio_actions (action_group,
799 modest_msg_edit_file_format_action_entries,
800 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
801 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
802 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
804 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
805 g_object_unref (action_group);
807 /* Load the UI definition */
808 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
811 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
812 g_clear_error (&error);
815 /* Add accelerators */
816 gtk_window_add_accel_group (GTK_WINDOW (obj),
817 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
819 parent_priv->menubar = NULL;
821 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
823 /* Note: This ModestPairList* must exist for as long as the combo
824 * that uses it, because the ModestComboBox uses the ID opaquely,
825 * so it can't know how to manage its memory. */
826 priv->from_field = modest_combo_box_new (NULL, g_str_equal);
828 priv->to_field = modest_recpt_editor_new ();
829 priv->cc_field = modest_recpt_editor_new ();
830 priv->bcc_field = modest_recpt_editor_new ();
831 subject_box = gtk_hbox_new (FALSE, 0);
832 priv->priority_icon = gtk_image_new ();
833 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
834 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
835 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
836 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
837 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
838 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
839 priv->add_attachment_button = gtk_button_new ();
840 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
841 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
842 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
843 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
844 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
845 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
846 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
847 priv->attachments_view = modest_attachments_view_new (NULL);
849 priv->header_box = gtk_vbox_new (FALSE, 0);
851 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
852 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
853 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
854 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
855 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
856 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
857 g_object_unref (size_group);
859 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
860 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
861 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
862 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
863 gtk_size_group_add_widget (size_group, priv->subject_field);
864 gtk_size_group_add_widget (size_group, priv->attachments_view);
865 g_object_unref (size_group);
867 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
868 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
869 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
870 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
871 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
872 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
873 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
876 priv->msg_body = wp_text_view_new ();
877 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
878 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
879 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
880 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
881 #if (GTK_MINOR_VERSION >= 10)
882 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
883 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
885 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
886 deserialize_type, TRUE);
888 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
890 priv->find_toolbar = hildon_find_toolbar_new (NULL);
891 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
893 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
895 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
896 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
897 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
898 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->scroll), TRUE);
900 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
902 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
903 priv->frame = gtk_frame_new (NULL);
904 gtk_box_pack_start (GTK_BOX(main_vbox), priv->frame, TRUE, TRUE, 0);
906 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
907 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
908 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
910 window_box = gtk_vbox_new (FALSE, 0);
911 gtk_container_add (GTK_CONTAINER(obj), window_box);
913 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
915 gtk_container_add (GTK_CONTAINER (priv->frame), priv->msg_body);
917 /* Set window icon */
918 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
920 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
921 g_object_unref (window_icon);
926 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
928 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
930 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
931 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
932 priv->clipboard_change_handler_id))
933 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
934 priv->clipboard_change_handler_id);
935 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
936 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
937 priv->default_clipboard_change_handler_id))
938 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
939 priv->default_clipboard_change_handler_id);
941 if (priv->account_removed_handler_id &&
942 g_signal_handler_is_connected (modest_runtime_get_account_store (),
943 priv->account_removed_handler_id))
944 g_signal_handler_disconnect(modest_runtime_get_account_store (),
945 priv->account_removed_handler_id);
949 modest_msg_edit_window_finalize (GObject *obj)
951 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
953 /* Sanity check: shouldn't be needed, the window mgr should
954 call this function before */
955 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
957 if (priv->clipboard_text != NULL) {
958 g_free (priv->clipboard_text);
959 priv->clipboard_text = NULL;
962 if (priv->draft_msg != NULL) {
963 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
964 if (TNY_IS_HEADER (header)) {
965 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
966 modest_window_mgr_unregister_header (mgr, header);
968 g_object_unref (priv->draft_msg);
969 priv->draft_msg = NULL;
971 if (priv->outbox_msg != NULL) {
972 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
973 if (TNY_IS_HEADER (header)) {
974 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
975 modest_window_mgr_unregister_header (mgr, header);
977 g_object_unref (priv->outbox_msg);
978 priv->outbox_msg = NULL;
980 if (priv->scroll_drag_timeout_id > 0) {
981 g_source_remove (priv->scroll_drag_timeout_id);
982 priv->scroll_drag_timeout_id = 0;
984 g_free (priv->msg_uid);
985 g_free (priv->last_search);
986 g_slist_free (priv->font_items_group);
987 g_slist_free (priv->size_items_group);
988 g_object_unref (priv->attachments);
989 g_object_unref (priv->images);
991 /* This had to stay alive for as long as the combobox that used it: */
992 modest_pair_list_free (priv->from_field_protos);
994 G_OBJECT_CLASS(parent_class)->finalize (obj);
998 pixbuf_from_stream (TnyStream *stream, const gchar *mime_type, guint64 *stream_size)
1000 GdkPixbufLoader *loader;
1006 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1008 if (loader == NULL) {
1014 tny_stream_reset (TNY_STREAM (stream));
1015 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1016 unsigned char read_buffer[128];
1018 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1020 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1024 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1025 g_object_ref (pixbuf);
1026 gdk_pixbuf_loader_close (loader, NULL);
1027 g_object_unref (loader);
1029 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1030 GdkPixbuf *new_pixbuf;
1032 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1033 gdk_pixbuf_get_width (pixbuf);
1034 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1035 g_object_unref (pixbuf);
1036 pixbuf = new_pixbuf;
1040 *stream_size = size;
1046 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1048 ModestMsgEditWindowPrivate *priv;
1051 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1053 for (iter = tny_list_create_iterator (attachments);
1054 !tny_iterator_is_done (iter);
1055 tny_iterator_next (iter)) {
1056 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1057 const gchar *cid = tny_mime_part_get_content_id (part);
1058 const gchar *mime_type = tny_mime_part_get_content_type (part);
1059 if ((cid != NULL)&&(mime_type != NULL)) {
1060 guint64 stream_size;
1061 TnyStream *stream = tny_mime_part_get_stream (part);
1062 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
1065 g_object_unref (stream);
1067 if (pixbuf != NULL) {
1068 priv->images_count ++;
1069 priv->images_size += stream_size;
1070 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1071 g_object_unref (pixbuf);
1074 g_object_unref (part);
1076 g_object_unref (iter);
1080 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1082 TnyMimePart *parent = NULL;
1083 const gchar *content_type = NULL;
1084 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1086 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1088 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1089 parent = g_object_ref (msg);
1090 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1091 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1094 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1095 iter = tny_list_create_iterator (parts);
1096 while (!tny_iterator_is_done (iter)) {
1098 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1099 content_type = tny_mime_part_get_content_type (part);
1100 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1104 g_object_unref (part);
1106 tny_iterator_next (iter);
1108 g_object_unref (iter);
1109 g_object_unref (parts);
1112 if (parent != NULL) {
1113 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1116 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1117 iter = tny_list_create_iterator (parts);
1118 while (!tny_iterator_is_done (iter)) {
1120 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1121 content_type = tny_mime_part_get_content_type (part);
1122 if (content_type && g_str_has_prefix (content_type, "image/")) {
1123 tny_list_prepend (priv->images, (GObject *) part);
1125 g_object_unref (part);
1126 tny_iterator_next (iter);
1128 g_object_unref (iter);
1129 g_object_unref (parts);
1130 g_object_unref (parent);
1135 update_last_cid (ModestMsgEditWindow *self, TnyList *attachments)
1138 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1140 for (iter = tny_list_create_iterator (attachments) ;
1141 !tny_iterator_is_done (iter);
1142 tny_iterator_next (iter)) {
1143 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1144 const gchar *cid = tny_mime_part_get_content_id (part);
1146 char *invalid = NULL;
1147 gint int_cid = strtol (cid, &invalid, 10);
1148 if ((invalid != NULL) && (*invalid == '\0') && (int_cid > priv->last_cid)) {
1149 priv->last_cid = int_cid;
1152 g_object_unref (part);
1154 g_object_unref (iter);
1158 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1161 const gchar *to, *cc, *bcc, *subject;
1163 ModestMsgEditWindowPrivate *priv;
1165 TnyHeaderFlags priority_flags;
1166 TnyFolder *msg_folder;
1167 gboolean is_html = FALSE;
1169 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1170 g_return_if_fail (TNY_IS_MSG (msg));
1172 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1174 header = tny_msg_get_header (msg);
1175 to = tny_header_get_to (header);
1176 cc = tny_header_get_cc (header);
1177 bcc = tny_header_get_bcc (header);
1178 subject = tny_header_get_subject (header);
1179 priority_flags = tny_header_get_priority (header);
1182 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1184 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1185 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1186 gtk_widget_show (priv->cc_caption);
1187 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1188 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1189 gtk_widget_hide (priv->cc_caption);
1192 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1193 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1194 gtk_widget_show (priv->bcc_caption);
1195 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1196 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1197 gtk_widget_hide (priv->bcc_caption);
1200 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1201 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1204 update_window_title (self);
1206 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1207 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1209 if ((body == NULL)||(body[0] == '\0')) {
1211 body = modest_text_utils_convert_to_html ("");
1214 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1215 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1218 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1221 /* Add attachments to the view */
1222 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1223 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1224 if (tny_list_get_length (priv->attachments) == 0) {
1225 gtk_widget_hide (priv->attachments_caption);
1227 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1228 gtk_widget_show_all (priv->attachments_caption);
1230 get_related_images (self, msg);
1231 update_last_cid (self, priv->attachments);
1232 update_last_cid (self, priv->images);
1233 replace_with_images (self, priv->images);
1235 if (preserve_is_rich && !is_html) {
1236 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1237 /* Get the default format required from configuration */
1238 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1239 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1242 /* Set the default focus depending on having already a To: field or not */
1243 if ((!to)||(*to == '\0')) {
1244 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1246 gtk_widget_grab_focus (priv->msg_body);
1249 /* TODO: lower priority, select in the From: combo to the
1250 value that comes from msg <- not sure, should it be
1253 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1255 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1256 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1258 modest_msg_edit_window_set_modified (self, FALSE);
1260 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1261 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1262 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1263 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1265 if (priv->msg_uid) {
1266 g_free (priv->msg_uid);
1267 priv->msg_uid = NULL;
1270 /* we should set a reference to the incoming message if it is a draft */
1271 msg_folder = tny_msg_get_folder (msg);
1273 if (modest_tny_folder_is_local_folder (msg_folder)) {
1274 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1275 if (type == TNY_FOLDER_TYPE_INVALID)
1276 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1278 if (type == TNY_FOLDER_TYPE_DRAFTS)
1279 priv->draft_msg = g_object_ref(msg);
1280 if (type == TNY_FOLDER_TYPE_OUTBOX)
1281 priv->outbox_msg = g_object_ref(msg);
1282 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1284 g_object_unref (msg_folder);
1289 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
1292 GList *item_children, *node;
1293 GtkWidget *bin_child;
1295 bin_child = gtk_bin_get_child (GTK_BIN(item));
1297 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
1299 for (node = item_children; node != NULL; node = g_list_next (node)) {
1300 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
1301 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
1304 g_list_free (item_children);
1308 menu_tool_button_dont_expand (GtkMenuToolButton *item)
1311 GList *item_children, *node;
1313 box = gtk_bin_get_child (GTK_BIN (item));
1314 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
1315 item_children = gtk_container_get_children (GTK_CONTAINER (box));
1317 for (node = item_children; node != NULL; node = g_list_next (node)) {
1318 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
1319 if (GTK_IS_TOGGLE_BUTTON (node->data))
1320 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
1321 else if (GTK_IS_BUTTON (node->data))
1322 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
1324 g_list_free (item_children);
1329 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1331 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1332 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1333 GtkWidget *placeholder;
1334 GtkWidget *tool_item;
1339 GtkWidget *sizes_menu;
1340 GtkWidget *fonts_menu;
1341 GSList *radio_group = NULL;
1342 GSList *node = NULL;
1346 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1347 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1349 /* Font color placeholder */
1350 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1351 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1354 tool_item = GTK_WIDGET (gtk_tool_item_new ());
1355 priv->font_color_button = hildon_color_button_new ();
1356 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
1357 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1358 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
1359 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1360 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1361 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1362 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1364 G_CALLBACK (modest_msg_edit_window_color_button_change),
1367 /* Font size and face placeholder */
1368 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1369 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1371 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1372 priv->size_tool_button_label = gtk_label_new (NULL);
1373 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1374 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1375 size_text,"</span>", NULL);
1376 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1378 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
1379 sizes_menu = gtk_menu_new ();
1380 priv->size_items_group = NULL;
1382 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1383 GtkWidget *size_menu_item;
1385 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1386 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
1387 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
1388 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
1389 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
1390 gtk_widget_show (size_menu_item);
1392 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
1396 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1397 GtkWidget *item = (GtkWidget *) node->data;
1398 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
1402 priv->size_items_group = g_slist_reverse (priv->size_items_group);
1403 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
1404 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1405 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1406 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1407 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1408 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1409 priv->font_size_toolitem = tool_item;
1412 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1413 priv->font_tool_button_label = gtk_label_new (NULL);
1414 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1415 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1417 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
1418 fonts_menu = gtk_menu_new ();
1419 priv->font_items_group = NULL;
1421 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1422 GtkWidget *font_menu_item;
1423 GtkWidget *child_label;
1425 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
1426 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
1427 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
1428 wp_get_font_name (font_index), "</span>", NULL);
1429 gtk_label_set_markup (GTK_LABEL (child_label), markup);
1432 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
1433 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
1434 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
1435 gtk_widget_show (font_menu_item);
1437 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
1440 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1441 GtkWidget *item = (GtkWidget *) node->data;
1442 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
1445 priv->font_items_group = g_slist_reverse (priv->font_items_group);
1446 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
1447 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1448 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1449 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1450 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1451 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1452 priv->font_face_toolitem = tool_item;
1454 /* Set expand and homogeneous for remaining items */
1455 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1456 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1457 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1458 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1459 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1460 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1461 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1462 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1463 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1465 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1466 will not show the tool items added to the placeholders) */
1467 gtk_widget_show_all (parent_priv->toolbar);
1469 /* Set the no show all *after* showing all items. We do not
1470 want the toolbar to be shown with a show all because it
1471 could go agains the gconf setting regarding showing or not
1472 the toolbar of the editor window */
1473 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1479 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean preserve_is_rich)
1482 ModestWindowPrivate *parent_priv;
1483 ModestMsgEditWindowPrivate *priv;
1484 ModestPair *account_pair = NULL;
1485 ModestDimmingRulesGroup *menu_rules_group = NULL;
1486 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1487 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1488 ModestWindowMgr *mgr = NULL;
1490 g_return_val_if_fail (msg, NULL);
1491 g_return_val_if_fail (account_name, NULL);
1493 mgr = modest_runtime_get_window_mgr ();
1495 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1497 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1498 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1500 /* Menubar. Update the state of some toggles */
1501 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1502 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
1503 priv->from_field_protos = get_transports ();
1504 modest_combo_box_set_pair_list (MODEST_COMBO_BOX (priv->from_field), priv->from_field_protos);
1505 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1506 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1509 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1511 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1513 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1515 account_pair = find_transport_from_message_sender (priv->from_field_protos, msg);
1516 if (account_pair == NULL) {
1517 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
1519 if (account_pair != NULL)
1520 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
1522 priv->original_account_name = account_pair ? (const gchar *) account_pair->first : NULL;
1524 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new ();
1525 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1526 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1527 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1528 /* Add common dimming rules */
1529 modest_dimming_rules_group_add_rules (menu_rules_group,
1530 modest_msg_edit_window_menu_dimming_entries,
1531 G_N_ELEMENTS (modest_msg_edit_window_menu_dimming_entries),
1532 MODEST_WINDOW (obj));
1533 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1534 modest_msg_edit_window_toolbar_dimming_entries,
1535 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1536 MODEST_WINDOW (obj));
1537 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_button,
1538 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1539 MODEST_WINDOW (obj));
1540 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1541 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1542 MODEST_WINDOW (obj));
1543 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1544 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1545 MODEST_WINDOW (obj));
1546 modest_dimming_rules_group_add_rules (clipboard_rules_group,
1547 modest_msg_edit_window_clipboard_dimming_entries,
1548 G_N_ELEMENTS (modest_msg_edit_window_clipboard_dimming_entries),
1549 MODEST_WINDOW (obj));
1550 /* Insert dimming rules group for this window */
1551 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1552 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1553 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1554 /* Checks the dimming rules */
1555 g_object_unref (menu_rules_group);
1556 g_object_unref (toolbar_rules_group);
1557 g_object_unref (clipboard_rules_group);
1558 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, MODEST_MSG_EDIT_WINDOW (obj));
1560 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1562 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1564 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1565 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1566 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1567 priv->update_caption_visibility = TRUE;
1569 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1571 /* Track account-removed signal, this window should be closed
1572 in the case we're creating a mail associated to the account
1574 priv->account_removed_handler_id =
1575 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1577 G_CALLBACK(on_account_removed),
1580 return (ModestWindow*) obj;
1584 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1586 GString **string_buffer = (GString **) user_data;
1588 *string_buffer = g_string_append (*string_buffer, buffer);
1594 * @result: A new string which should be freed with g_free().
1597 get_formatted_data (ModestMsgEditWindow *edit_window)
1599 ModestMsgEditWindowPrivate *priv;
1600 GString *string_buffer = g_string_new ("");
1602 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1604 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1606 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1608 return g_string_free (string_buffer, FALSE);
1613 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1616 const gchar *account_name;
1617 ModestMsgEditWindowPrivate *priv;
1618 TnyIterator *att_iter;
1620 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1622 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1624 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1625 g_return_val_if_fail (account_name, NULL);
1628 /* don't free these (except from) */
1629 data = g_slice_new0 (MsgData);
1630 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1632 data->account_name = g_strdup (account_name);
1633 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1634 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1635 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1636 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1637 if (priv->draft_msg) {
1638 data->draft_msg = g_object_ref (priv->draft_msg);
1639 } else if (priv->outbox_msg) {
1640 data->draft_msg = g_object_ref (priv->outbox_msg);
1642 data->draft_msg = NULL;
1645 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1647 gtk_text_buffer_get_bounds (buf, &b, &e);
1648 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1650 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1651 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1653 data->html_body = NULL;
1655 /* deep-copy the data */
1656 att_iter = tny_list_create_iterator (priv->attachments);
1657 data->attachments = NULL;
1658 while (!tny_iterator_is_done (att_iter)) {
1659 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1660 if (!(TNY_IS_MIME_PART(part))) {
1661 g_warning ("strange data in attachment list");
1662 g_object_unref (part);
1663 tny_iterator_next (att_iter);
1666 data->attachments = g_list_append (data->attachments,
1668 tny_iterator_next (att_iter);
1670 g_object_unref (att_iter);
1672 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1673 att_iter = tny_list_create_iterator (priv->images);
1674 data->images = NULL;
1675 while (!tny_iterator_is_done (att_iter)) {
1676 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1678 if (!(TNY_IS_MIME_PART(part))) {
1679 g_warning ("strange data in attachment list");
1680 g_object_unref (part);
1681 tny_iterator_next (att_iter);
1684 cid = tny_mime_part_get_content_id (part);
1686 gchar *image_tag_id;
1687 GtkTextTag *image_tag;
1689 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1690 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1691 g_free (image_tag_id);
1693 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1695 ((gtk_text_iter_has_tag (&iter, image_tag))||
1696 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1697 data->images = g_list_append (data->images,
1698 g_object_ref (part));
1700 g_object_unref (part);
1701 tny_iterator_next (att_iter);
1703 g_object_unref (att_iter);
1705 data->priority_flags = priv->priority_flags;
1712 unref_gobject (GObject *obj, gpointer data)
1714 if (!G_IS_OBJECT(obj))
1716 g_object_unref (obj);
1720 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1723 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1731 g_free (data->from);
1732 g_free (data->subject);
1733 g_free (data->plain_body);
1734 g_free (data->html_body);
1735 g_free (data->account_name);
1737 if (data->draft_msg != NULL) {
1738 g_object_unref (data->draft_msg);
1739 data->draft_msg = NULL;
1742 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1743 g_list_free (data->attachments);
1744 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1745 g_list_free (data->images);
1747 g_slice_free (MsgData, data);
1751 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1753 guint64 *parts_size)
1755 ModestMsgEditWindowPrivate *priv;
1757 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1759 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1761 /* TODO: add images */
1762 *parts_size += priv->images_size;
1763 *parts_count += priv->images_count;
1768 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1771 ModestMsgEditWindowPrivate *priv = NULL;
1772 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1774 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1776 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1778 return MODEST_MSG_EDIT_FORMAT_HTML;
1780 return MODEST_MSG_EDIT_FORMAT_TEXT;
1784 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1785 ModestMsgEditFormat format)
1787 ModestMsgEditWindowPrivate *priv;
1789 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1790 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1793 case MODEST_MSG_EDIT_FORMAT_HTML:
1794 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1796 case MODEST_MSG_EDIT_FORMAT_TEXT:
1797 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1800 g_return_if_reached ();
1804 ModestMsgEditFormatState *
1805 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1807 ModestMsgEditFormatState *format_state = NULL;
1808 ModestMsgEditWindowPrivate *priv;
1809 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1811 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1812 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1814 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1816 format_state = g_new0 (ModestMsgEditFormatState, 1);
1817 format_state->bold = buffer_format->bold&0x1;
1818 format_state->italics = buffer_format->italic&0x1;
1819 format_state->bullet = buffer_format->bullet&0x1;
1820 format_state->color = buffer_format->color;
1821 format_state->font_size = buffer_format->font_size;
1822 format_state->font_family = wp_get_font_name (buffer_format->font);
1823 format_state->justification = buffer_format->justification;
1824 g_free (buffer_format);
1826 return format_state;
1831 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1832 const ModestMsgEditFormatState *format_state)
1834 ModestMsgEditWindowPrivate *priv;
1835 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1836 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1837 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1838 g_return_if_fail (format_state != NULL);
1840 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1841 gtk_widget_grab_focus (priv->msg_body);
1842 buffer_format->bold = (format_state->bold != FALSE);
1843 buffer_format->italic = (format_state->italics != FALSE);
1844 buffer_format->color = format_state->color;
1845 buffer_format->font_size = format_state->font_size;
1846 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1847 buffer_format->justification = format_state->justification;
1848 buffer_format->bullet = format_state->bullet;
1850 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1852 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1853 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1854 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1855 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1856 buffer_format->cs.font = (buffer_format->font != current_format->font);
1857 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1858 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1860 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1861 if (buffer_format->cs.bold) {
1862 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1863 GINT_TO_POINTER (buffer_format->bold&0x1));
1865 if (buffer_format->cs.italic) {
1866 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1867 GINT_TO_POINTER (buffer_format->italic&0x1));
1869 if (buffer_format->cs.color) {
1870 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1871 GINT_TO_POINTER (&(buffer_format->color)));
1873 if (buffer_format->cs.font_size) {
1874 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1875 GINT_TO_POINTER (buffer_format->font_size));
1877 if (buffer_format->cs.justification) {
1878 switch (buffer_format->justification) {
1879 case GTK_JUSTIFY_LEFT:
1880 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1881 GINT_TO_POINTER(TRUE));
1883 case GTK_JUSTIFY_CENTER:
1884 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1885 GINT_TO_POINTER(TRUE));
1887 case GTK_JUSTIFY_RIGHT:
1888 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1889 GINT_TO_POINTER(TRUE));
1896 if (buffer_format->cs.font) {
1897 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1898 GINT_TO_POINTER (buffer_format->font));
1900 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1901 if (buffer_format->cs.bullet) {
1902 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
1903 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
1905 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1907 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
1909 g_free (current_format);
1914 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1916 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1918 ModestWindowPrivate *parent_priv;
1919 ModestMsgEditWindowPrivate *priv;
1920 GtkWidget *new_size_menuitem;
1921 GtkWidget *new_font_menuitem;
1923 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1924 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1926 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1927 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1928 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1929 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1931 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1932 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1933 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1936 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1938 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1939 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1941 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1942 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1944 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
1945 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
1948 switch (buffer_format->justification)
1950 case GTK_JUSTIFY_LEFT:
1951 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1953 case GTK_JUSTIFY_CENTER:
1954 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1956 case GTK_JUSTIFY_RIGHT:
1957 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1964 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1966 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1967 G_CALLBACK (modest_msg_edit_window_color_button_change),
1969 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1970 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1971 G_CALLBACK (modest_msg_edit_window_color_button_change),
1974 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1975 buffer_format->font_size))->data);
1976 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1980 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1981 markup = g_strconcat ("<span font_family='Sans'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1982 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1984 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1985 G_CALLBACK (modest_msg_edit_window_size_change),
1987 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1988 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1989 G_CALLBACK (modest_msg_edit_window_size_change),
1993 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1994 buffer_format->font))->data);
1995 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1999 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
2000 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2001 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2003 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
2004 G_CALLBACK (modest_msg_edit_window_font_change),
2006 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
2007 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
2008 G_CALLBACK (modest_msg_edit_window_font_change),
2012 g_free (buffer_format);
2016 #ifdef MODEST_HILDON_VERSION_0
2018 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2021 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2022 ModestMsgEditWindowPrivate *priv;
2023 GtkWidget *dialog = NULL;
2025 GdkColor *new_color = NULL;
2027 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2028 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2030 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2031 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2032 g_free (buffer_format);
2034 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2035 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2036 if (new_color != NULL) {
2037 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2038 (gpointer) new_color);
2041 gtk_widget_destroy (dialog);
2046 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2049 ModestMsgEditWindowPrivate *priv;
2050 GtkWidget *dialog = NULL;
2052 GdkColor *old_color = NULL;
2053 const GdkColor *new_color = NULL;
2055 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2056 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2058 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2059 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2061 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2062 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2063 if (new_color != NULL)
2064 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2066 gtk_widget_destroy (dialog);
2072 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2075 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2076 ModestMsgEditWindowPrivate *priv;
2077 GtkWidget *dialog = NULL;
2079 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2080 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2082 dialog = hildon_color_chooser_new ();
2083 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2084 g_free (buffer_format);
2086 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2088 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2089 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2092 gtk_widget_destroy (dialog);
2097 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2100 ModestMsgEditWindowPrivate *priv;
2101 GtkWidget *dialog = NULL;
2102 GdkColor *old_color = NULL;
2104 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2105 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2107 dialog = hildon_color_chooser_new ();
2108 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2110 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2112 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2113 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2115 gtk_widget_destroy (dialog);
2118 #endif /*!MODEST_HILDON_VERSION_0*/
2122 static TnyStream* create_stream_for_uri (const gchar* uri)
2127 TnyStream *result = NULL;
2129 GnomeVFSHandle *handle = NULL;
2130 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2131 if (test == GNOME_VFS_OK) {
2132 /* Create the tinymail stream: */
2133 /* Presumably tinymai will call gnome_vfs_close (handle) later. */
2134 result = TNY_STREAM (tny_vfs_stream_new (handle));
2141 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2144 ModestMsgEditWindowPrivate *priv;
2145 GtkWidget *dialog = NULL;
2147 GSList *uris = NULL;
2148 GSList *uri_node = NULL;
2150 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2152 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2153 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2154 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2156 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2158 response = gtk_dialog_run (GTK_DIALOG (dialog));
2160 case GTK_RESPONSE_OK:
2161 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2166 gtk_widget_destroy (dialog);
2168 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2170 GnomeVFSHandle *handle = NULL;
2171 GnomeVFSResult result;
2172 GtkTextIter position;
2173 GtkTextMark *insert_mark;
2175 uri = (const gchar *) uri_node->data;
2176 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2177 if (result == GNOME_VFS_OK) {
2179 GnomeVFSFileInfo *info;
2180 gchar *filename, *basename, *escaped_filename;
2181 TnyMimePart *mime_part;
2183 const gchar *mime_type = NULL;
2184 GnomeVFSURI *vfs_uri;
2185 guint64 stream_size;
2187 vfs_uri = gnome_vfs_uri_new (uri);
2189 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2190 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2191 g_free (escaped_filename);
2192 gnome_vfs_uri_unref (vfs_uri);
2193 info = gnome_vfs_file_info_new ();
2195 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2196 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2198 mime_type = gnome_vfs_file_info_get_mime_type (info);
2200 mime_part = tny_platform_factory_new_mime_part
2201 (modest_runtime_get_platform_factory ());
2203 TnyStream *stream = create_stream_for_uri (uri);
2204 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2206 content_id = g_strdup_printf ("%d", priv->last_cid);
2207 tny_mime_part_set_content_id (mime_part, content_id);
2208 g_free (content_id);
2211 basename = g_path_get_basename (filename);
2212 tny_mime_part_set_filename (mime_part, basename);
2215 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
2217 if (pixbuf != NULL) {
2218 priv->images_size += stream_size;
2219 priv->images_count ++;
2220 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2221 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2222 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
2225 tny_list_prepend (priv->images, (GObject *) mime_part);
2226 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2228 g_object_unref (mime_part);
2229 gnome_vfs_file_info_unref (info);
2238 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2240 GtkWidget *dialog = NULL;
2242 GSList *uris = NULL;
2245 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2246 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2247 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2249 response = gtk_dialog_run (GTK_DIALOG (dialog));
2251 case GTK_RESPONSE_OK:
2252 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2257 gtk_widget_destroy (dialog);
2259 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2260 const gchar *uri = (const gchar *) uri_node->data;
2261 modest_msg_edit_window_attach_file_one (window, uri);
2263 g_slist_foreach (uris, (GFunc) g_free, NULL);
2264 g_slist_free (uris);
2268 modest_msg_edit_window_attach_file_one (
2269 ModestMsgEditWindow *window,
2272 GnomeVFSHandle *handle = NULL;
2273 ModestMsgEditWindowPrivate *priv;
2274 GnomeVFSResult result;
2276 g_return_if_fail (window);
2277 g_return_if_fail (uri);
2279 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2281 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2282 if (result == GNOME_VFS_OK) {
2283 TnyMimePart *mime_part;
2285 const gchar *mime_type = NULL;
2287 gchar *escaped_filename;
2290 GnomeVFSFileInfo *info;
2291 GnomeVFSURI *vfs_uri;
2293 vfs_uri = gnome_vfs_uri_new (uri);
2296 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2297 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2298 g_free (escaped_filename);
2299 gnome_vfs_uri_unref (vfs_uri);
2301 info = gnome_vfs_file_info_new ();
2303 if (gnome_vfs_get_file_info (uri,
2305 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2307 mime_type = gnome_vfs_file_info_get_mime_type (info);
2308 mime_part = tny_platform_factory_new_mime_part
2309 (modest_runtime_get_platform_factory ());
2310 stream = TNY_STREAM (tny_vfs_stream_new (handle));
2312 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2314 g_object_unref (stream);
2316 content_id = g_strdup_printf ("%d", priv->last_cid);
2317 tny_mime_part_set_content_id (mime_part, content_id);
2318 g_free (content_id);
2321 basename = g_path_get_basename (filename);
2322 tny_mime_part_set_filename (mime_part, basename);
2325 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2326 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2328 info->size == 0, info->size);
2329 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2330 gtk_widget_show_all (priv->attachments_caption);
2331 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2333 g_object_unref (mime_part);
2334 gnome_vfs_file_info_unref (info);
2339 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2342 ModestMsgEditWindowPrivate *priv;
2345 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2346 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2348 if (att_list == NULL) {
2349 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2351 g_object_ref (att_list);
2354 if (tny_list_get_length (att_list) == 0) {
2355 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2357 GtkWidget *confirmation_dialog = NULL;
2358 gboolean dialog_response;
2359 gchar *message = NULL;
2360 gchar *filename = NULL;
2362 if (tny_list_get_length (att_list) == 1) {
2364 iter = tny_list_create_iterator (att_list);
2365 part = (TnyMimePart *) tny_iterator_get_current (iter);
2366 g_object_unref (iter);
2367 if (TNY_IS_MSG (part)) {
2368 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2370 filename = g_strdup (tny_header_get_subject (header));
2371 g_object_unref (header);
2373 if (filename == NULL) {
2374 filename = g_strdup (_("mail_va_no_subject"));
2377 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2379 g_object_unref (part);
2381 filename = g_strdup ("");
2383 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
2384 (tny_list_get_length (att_list) == 1)), filename);
2386 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
2388 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
2389 gtk_widget_destroy (confirmation_dialog);
2390 if (!dialog_response) {
2391 g_object_unref (att_list);
2394 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
2396 for (iter = tny_list_create_iterator (att_list);
2397 !tny_iterator_is_done (iter);
2398 tny_iterator_next (iter)) {
2399 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2400 const gchar *att_id;
2401 tny_list_remove (priv->attachments, (GObject *) mime_part);
2403 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2405 if (tny_list_get_length (priv->attachments) == 0)
2406 gtk_widget_hide (priv->attachments_caption);
2407 att_id = tny_mime_part_get_content_id (mime_part);
2409 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2411 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2412 g_object_unref (mime_part);
2414 g_object_unref (iter);
2417 g_object_unref (att_list);
2419 /* if the last attachment has been removed, focus the Subject: field */
2420 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2421 gtk_widget_grab_focus (priv->subject_field);
2425 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2428 ModestMsgEditWindowPrivate *priv;
2429 GdkColor *new_color;
2430 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2432 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2433 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2436 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2438 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2440 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2442 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2447 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
2450 ModestMsgEditWindowPrivate *priv;
2451 gint new_size_index;
2452 ModestMsgEditWindow *window;
2455 window = MODEST_MSG_EDIT_WINDOW (userdata);
2456 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2457 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2459 if (gtk_check_menu_item_get_active (menu_item)) {
2461 WPTextBufferFormat format;
2463 memset (&format, 0, sizeof (format));
2464 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2466 label = gtk_bin_get_child (GTK_BIN (menu_item));
2468 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
2469 format.cs.font_size = TRUE;
2470 format.cs.text_position = TRUE;
2471 format.cs.font = TRUE;
2472 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
2473 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2475 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2476 GINT_TO_POINTER (wp_get_font_size_index (new_size_index, 12))))
2477 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2479 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2480 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
2481 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2487 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
2490 ModestMsgEditWindowPrivate *priv;
2491 gint new_font_index;
2492 ModestMsgEditWindow *window;
2495 window = MODEST_MSG_EDIT_WINDOW (userdata);
2496 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2497 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2499 if (gtk_check_menu_item_get_active (menu_item)) {
2502 label = gtk_bin_get_child (GTK_BIN (menu_item));
2504 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
2506 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2507 GINT_TO_POINTER(new_font_index)))
2508 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2510 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2511 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2512 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2518 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
2520 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
2521 ModestWindowPrivate *parent_priv;
2522 ModestWindowMgr *mgr;
2523 gboolean is_fullscreen;
2524 GtkAction *fs_toggle_action;
2527 mgr = modest_runtime_get_window_mgr ();
2528 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
2530 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
2532 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2533 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2534 if (is_fullscreen != active)
2535 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2543 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2546 ModestMsgEditWindowPrivate *priv = NULL;
2547 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2549 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2550 if (!priv->update_caption_visibility)
2553 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2555 gtk_widget_show (priv->cc_caption);
2557 gtk_widget_hide (priv->cc_caption);
2559 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2563 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2566 ModestMsgEditWindowPrivate *priv = NULL;
2567 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2569 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2570 if (!priv->update_caption_visibility)
2573 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2575 gtk_widget_show (priv->bcc_caption);
2577 gtk_widget_hide (priv->bcc_caption);
2579 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2583 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2584 ModestRecptEditor *editor)
2586 ModestMsgEditWindowPrivate *priv;
2588 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2589 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2590 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2592 if (editor == NULL) {
2593 GtkWidget *view_focus;
2594 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2596 /* This code should be kept in sync with ModestRecptEditor. The
2597 textview inside the recpt editor is the one that really gets the
2598 focus. As it's inside a scrolled window, and this one inside the
2599 hbox recpt editor inherits from, we'll need to go up in the
2600 hierarchy to know if the text view is part of the recpt editor
2601 or if it's a different text entry */
2603 if (gtk_widget_get_parent (view_focus)) {
2604 GtkWidget *first_parent;
2606 first_parent = gtk_widget_get_parent (view_focus);
2607 if (gtk_widget_get_parent (first_parent) &&
2608 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2609 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2614 editor = MODEST_RECPT_EDITOR (priv->to_field);
2618 modest_address_book_select_addresses (editor);
2623 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2625 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2627 modest_msg_edit_window_open_addressbook (window, NULL);
2631 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2632 gboolean show_toolbar)
2634 ModestWindowPrivate *parent_priv;
2635 const gchar *action_name;
2638 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2639 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2641 /* We can not just use the code of
2642 modest_msg_edit_window_setup_toolbar because it has a
2643 mixture of both initialization and creation code. */
2645 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2647 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2649 /* Update also the actions (to update the toggles in the
2650 menus), we have to do it manually because some other window
2651 of the same time could have changed it (remember that the
2652 toolbar fullscreen mode is shared by all the windows of the
2654 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
2655 action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarFullScreenMenu";
2657 action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarNormalScreenMenu";
2659 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
2660 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
2666 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2667 TnyHeaderFlags priority_flags)
2669 ModestMsgEditWindowPrivate *priv;
2670 ModestWindowPrivate *parent_priv;
2672 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2674 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2675 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2677 if (priv->priority_flags != priority_flags) {
2678 GtkAction *priority_action = NULL;
2680 priv->priority_flags = priority_flags;
2682 switch (priority_flags) {
2683 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2684 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2685 gtk_widget_show (priv->priority_icon);
2686 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2687 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2689 case TNY_HEADER_FLAG_LOW_PRIORITY:
2690 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2691 gtk_widget_show (priv->priority_icon);
2692 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2693 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2696 gtk_widget_hide (priv->priority_icon);
2697 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2698 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2701 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2702 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2707 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2710 ModestMsgEditWindowPrivate *priv;
2711 ModestWindowPrivate *parent_priv;
2712 gint current_format;
2714 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2716 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2717 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2719 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2720 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2722 if (current_format != file_format) {
2723 switch (file_format) {
2724 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2725 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2726 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
2728 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2732 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2733 response = gtk_dialog_run (GTK_DIALOG (dialog));
2734 gtk_widget_destroy (dialog);
2735 if (response == GTK_RESPONSE_OK) {
2736 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2738 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2739 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
2744 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2749 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2752 ModestMsgEditWindowPrivate *priv;
2753 WPTextBufferFormat oldfmt, fmt;
2754 gint old_position = 0;
2758 GdkColor *color = NULL;
2759 gboolean bold, bold_set, italic, italic_set;
2760 gboolean underline, underline_set;
2761 gboolean strikethrough, strikethrough_set;
2762 gboolean position_set;
2763 gboolean font_size_set, font_set, color_set;
2766 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2767 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2769 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2771 /* First we get the currently selected font information */
2772 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2774 switch (oldfmt.text_position) {
2775 case TEXT_POSITION_NORMAL:
2778 case TEXT_POSITION_SUPERSCRIPT:
2786 g_object_set (G_OBJECT (dialog),
2787 "bold", oldfmt.bold != FALSE,
2788 "bold-set", !oldfmt.cs.bold,
2789 "underline", oldfmt.underline != FALSE,
2790 "underline-set", !oldfmt.cs.underline,
2791 "italic", oldfmt.italic != FALSE,
2792 "italic-set", !oldfmt.cs.italic,
2793 "strikethrough", oldfmt.strikethrough != FALSE,
2794 "strikethrough-set", !oldfmt.cs.strikethrough,
2795 "color", &oldfmt.color,
2796 "color-set", !oldfmt.cs.color,
2797 "size", wp_font_size[oldfmt.font_size],
2798 "size-set", !oldfmt.cs.font_size,
2799 "position", old_position,
2800 "position-set", !oldfmt.cs.text_position,
2801 "family", wp_get_font_name (oldfmt.font),
2802 "family-set", !oldfmt.cs.font,
2805 gtk_widget_show_all (dialog);
2806 response = gtk_dialog_run (GTK_DIALOG (dialog));
2807 if (response == GTK_RESPONSE_OK) {
2809 g_object_get( dialog,
2811 "bold-set", &bold_set,
2812 "underline", &underline,
2813 "underline-set", &underline_set,
2815 "italic-set", &italic_set,
2816 "strikethrough", &strikethrough,
2817 "strikethrough-set", &strikethrough_set,
2819 "color-set", &color_set,
2821 "size-set", &font_size_set,
2822 "family", &font_name,
2823 "family-set", &font_set,
2824 "position", &position,
2825 "position-set", &position_set,
2830 if (response == GTK_RESPONSE_OK) {
2831 memset(&fmt, 0, sizeof(fmt));
2837 fmt.italic = italic;
2838 fmt.cs.italic = TRUE;
2840 if (underline_set) {
2841 fmt.underline = underline;
2842 fmt.cs.underline = TRUE;
2844 if (strikethrough_set) {
2845 fmt.strikethrough = strikethrough;
2846 fmt.cs.strikethrough = TRUE;
2851 ? TEXT_POSITION_NORMAL
2852 : ( ( position == 1 )
2853 ? TEXT_POSITION_SUPERSCRIPT
2854 : TEXT_POSITION_SUBSCRIPT );
2855 fmt.cs.text_position = TRUE;
2856 fmt.font_size = oldfmt.font_size;
2860 fmt.cs.color = TRUE;
2863 fmt.font = wp_get_font_index(font_name,
2868 if (font_size_set) {
2869 fmt.cs.font_size = TRUE;
2870 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
2872 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2873 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2875 gtk_widget_destroy (dialog);
2877 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2881 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2883 ModestMsgEditWindowPrivate *priv;
2885 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2886 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2888 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2890 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2891 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2896 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2898 ModestMsgEditWindowPrivate *priv;
2900 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2901 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2903 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2905 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2906 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2911 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2913 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2915 priv->can_undo = can_undo;
2919 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2921 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2923 priv->can_redo = can_redo;
2927 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
2929 ModestMsgEditWindowPrivate *priv;
2930 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2931 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2933 return priv->can_undo;
2937 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
2939 ModestMsgEditWindowPrivate *priv;
2940 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2941 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2943 return priv->can_redo;
2948 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2951 GtkTextIter match_start, match_end;
2953 if (image_id == NULL)
2956 gtk_text_buffer_get_start_iter (buffer, &iter);
2958 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2959 GSList *tags = gtk_text_iter_get_tags (&match_start);
2961 for (node = tags; node != NULL; node = g_slist_next (node)) {
2962 GtkTextTag *tag = (GtkTextTag *) node->data;
2963 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2964 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2965 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2967 offset = gtk_text_iter_get_offset (&match_start);
2968 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2969 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2973 gtk_text_iter_forward_char (&iter);
2978 message_is_empty (ModestMsgEditWindow *window)
2980 ModestMsgEditWindowPrivate *priv = NULL;
2982 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2983 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2985 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
2986 * so we can ignore markup.
2988 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
2991 count = gtk_text_buffer_get_char_count (buf);
2997 msg_body_focus (GtkWidget *focus,
2998 GdkEventFocus *event,
3002 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3003 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3004 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3009 recpt_field_changed (GtkTextBuffer *buffer,
3010 ModestMsgEditWindow *editor)
3012 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3013 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3017 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3019 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3020 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3024 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3027 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3028 GtkTextBuffer *buffer;
3030 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3031 gtk_text_buffer_set_modified (buffer, modified);
3032 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3033 gtk_text_buffer_set_modified (buffer, modified);
3034 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3035 gtk_text_buffer_set_modified (buffer, modified);
3036 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3040 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3042 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3043 const char *account_name;
3044 GtkTextBuffer *buffer;
3046 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3047 if (gtk_text_buffer_get_modified (buffer))
3049 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3050 if (gtk_text_buffer_get_modified (buffer))
3052 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3053 if (gtk_text_buffer_get_modified (buffer))
3055 if (gtk_text_buffer_get_modified (priv->text_buffer))
3057 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
3058 if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3069 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3071 ModestMsgEditWindowPrivate *priv = NULL;
3073 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3074 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3076 /* check if there's no recipient added */
3077 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3078 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3079 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3080 /* no recipient contents, then select contacts */
3081 modest_msg_edit_window_open_addressbook (window, NULL);
3085 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3086 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3089 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3090 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3093 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3094 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3098 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3099 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3100 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3107 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3108 ModestMsgEditWindow *window)
3110 modest_msg_edit_window_offer_attach_file (window);
3114 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3116 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3118 return priv->clipboard_text;
3122 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3124 ModestMsgEditWindow *window)
3126 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3127 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3129 if (!GTK_WIDGET_VISIBLE (window))
3132 text = gtk_clipboard_wait_for_text (selection_clipboard);
3134 if (priv->clipboard_text != NULL) {
3135 g_free (priv->clipboard_text);
3137 priv->clipboard_text = text;
3139 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3142 subject_field_move_cursor (GtkEntry *entry,
3143 GtkMovementStep step,
3148 if (!GTK_WIDGET_VISIBLE (window))
3151 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3155 update_window_title (ModestMsgEditWindow *window)
3157 ModestMsgEditWindowPrivate *priv = NULL;
3158 const gchar *subject;
3160 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3161 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3162 if (subject == NULL || subject[0] == '\0')
3163 subject = _("mail_va_new_email");
3165 gtk_window_set_title (GTK_WINDOW (window), subject);
3170 subject_field_changed (GtkEditable *editable,
3171 ModestMsgEditWindow *window)
3173 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3174 update_window_title (window);
3175 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3176 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3177 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3181 subject_field_insert_text (GtkEditable *editable,
3183 gint new_text_length,
3185 ModestMsgEditWindow *window)
3187 GString *result = g_string_new ("");
3189 gint result_len = 0;
3190 const gchar *entry_text = NULL;
3193 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3194 old_length = g_utf8_strlen (entry_text, -1);
3196 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3197 gunichar c = g_utf8_get_char_validated (current, 8);
3198 /* Invalid unichar, stop */
3204 result = g_string_append_unichar (result, c);
3208 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3209 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3212 /* Prevent endless recursion */
3213 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3214 g_signal_emit_by_name (editable, "insert-text",
3215 (gpointer) result->str, (gpointer) result->len,
3216 (gpointer) position, (gpointer) window);
3217 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3221 if (result_len + old_length > 1000) {
3222 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3223 dgettext("hildon-common-strings",
3224 "ckdg_ib_maximum_characters_reached"));
3227 g_string_free (result, TRUE);
3231 text_buffer_insert_text (GtkTextBuffer *buffer,
3234 gint new_text_length,
3235 ModestMsgEditWindow *window)
3237 GString *result = g_string_new ("");
3239 gint result_len = 0;
3240 gboolean changed = FALSE;
3242 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3243 gunichar c = g_utf8_get_char_validated (current, 8);
3244 /* Invalid unichar, stop */
3250 result = g_string_append_c (result, ' ');
3254 result = g_string_append_unichar (result, c);
3260 g_signal_stop_emission_by_name (G_OBJECT (buffer), "insert-text");
3261 g_signal_handlers_block_by_func(G_OBJECT(buffer), G_CALLBACK(text_buffer_insert_text), window);
3262 g_signal_emit_by_name (buffer, "insert-text",
3264 (gpointer) result->str, (gpointer) result->len,
3266 g_signal_handlers_unblock_by_func(G_OBJECT(buffer), G_CALLBACK(text_buffer_insert_text), window);
3269 g_string_free (result, TRUE);
3273 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3276 ModestMsgEditWindowPrivate *priv = NULL;
3278 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3279 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3281 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3284 gtk_widget_show_all (priv->find_toolbar);
3285 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3287 gtk_widget_hide_all (priv->find_toolbar);
3288 gtk_widget_grab_focus (priv->msg_body);
3294 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3296 GtkTextIter *match_start,
3297 GtkTextIter *match_end)
3299 GtkTextIter end_iter;
3300 gchar *str_casefold;
3303 gchar *range_casefold;
3306 gboolean result = FALSE;
3313 gtk_text_iter_forward_to_end (&end_iter);
3315 str_casefold = g_utf8_casefold (str, -1);
3316 str_chars_n = strlen (str);
3318 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3319 range_casefold = g_utf8_casefold (range_text, -1);
3320 range_chars_n = strlen (range_casefold);
3322 if (range_chars_n < str_chars_n) {
3323 g_free (str_casefold);
3324 g_free (range_text);
3325 g_free (range_casefold);
3329 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3330 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3331 if (!g_utf8_collate (range_subtext, str_casefold)) {
3332 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3334 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3335 match_start, match_end, NULL);
3336 g_free (found_text);
3338 g_free (range_subtext);
3342 g_free (str_casefold);
3343 g_free (range_text);
3344 g_free (range_casefold);
3351 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3352 ModestMsgEditWindow *window)
3354 gchar *current_search = NULL;
3355 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3357 GtkTextIter selection_start, selection_end;
3358 GtkTextIter match_start, match_end;
3359 gboolean continue_search = FALSE;
3361 if (message_is_empty (window)) {
3362 g_free (priv->last_search);
3363 priv->last_search = NULL;
3364 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3368 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3369 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3370 g_free (current_search);
3371 g_free (priv->last_search);
3372 priv->last_search = NULL;
3373 /* Information banner about empty search */
3374 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
3378 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3379 continue_search = TRUE;
3381 g_free (priv->last_search);
3382 priv->last_search = g_strdup (current_search);
3385 if (continue_search) {
3386 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3387 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3388 &match_start, &match_end);
3390 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
3392 GtkTextIter buffer_start;
3393 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3394 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3395 &match_start, &match_end);
3397 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
3400 /* Mark as selected the string found in search */
3402 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3403 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3404 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3406 g_free (priv->last_search);
3407 priv->last_search = NULL;
3409 g_free (current_search);
3413 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3414 ModestMsgEditWindow *window)
3416 GtkToggleAction *toggle;
3417 ModestWindowPrivate *parent_priv;
3418 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3420 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
3421 gtk_toggle_action_set_active (toggle, FALSE);
3425 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3427 ModestMsgEditWindowPrivate *priv;
3429 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3434 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3437 ModestMsgEditWindowPrivate *priv;
3439 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3445 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3448 ModestMsgEditWindowPrivate *priv;
3449 TnyHeader *header = NULL;
3451 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3452 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3454 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3455 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3457 if (priv->draft_msg != NULL) {
3458 g_object_unref (priv->draft_msg);
3461 if (draft != NULL) {
3462 g_object_ref (draft);
3463 header = tny_msg_get_header (draft);
3464 if (priv->msg_uid) {
3465 g_free (priv->msg_uid);
3466 priv->msg_uid = NULL;
3468 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3469 if (GTK_WIDGET_REALIZED (window))
3470 modest_window_mgr_register_window (mgr, MODEST_WINDOW (window));
3473 priv->draft_msg = draft;
3477 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3478 GtkTextIter *start, GtkTextIter *end,
3481 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3482 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3485 if (tag == NULL+13) return;
3486 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3487 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3488 replace_with_images (window, priv->images);
3493 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3496 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3498 g_return_if_fail (TNY_IS_MIME_PART (part));
3499 tny_list_prepend (priv->attachments, (GObject *) part);
3500 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3501 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3502 gtk_widget_show_all (priv->attachments_caption);
3503 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3507 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3509 ModestMsgEditWindowPrivate *priv;
3511 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3512 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3514 return priv->msg_uid;
3518 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3519 ModestMsgEditWindowWidgetType widget_type)
3521 ModestMsgEditWindowPrivate *priv;
3523 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3524 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3526 switch (widget_type) {
3527 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3528 return priv->msg_body;
3530 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3531 return priv->to_field;
3533 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3534 return priv->cc_field;
3536 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3537 return priv->bcc_field;
3539 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3540 return priv->subject_field;
3542 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3543 return priv->attachments_view;
3551 remove_tags (WPTextBuffer *buffer)
3553 GtkTextIter start, end;
3555 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3556 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3558 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3562 on_account_removed (TnyAccountStore *account_store,
3563 TnyAccount *account,
3566 /* Do nothing if it's a store account, because we use the
3567 transport to send the messages */
3568 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3569 const gchar *parent_acc = NULL;
3570 const gchar *our_acc = NULL;
3572 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3573 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3574 /* Close this window if I'm showing a message of the removed account */
3575 if (strcmp (parent_acc, our_acc) == 0)
3576 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3581 on_zoom_minus_plus_not_implemented (ModestWindow *window)
3583 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3585 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
3591 set_zoom_do_nothing (ModestWindow *window,
3597 get_zoom_do_nothing (ModestWindow *window)