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 gtk_widget_show_all (GTK_WIDGET (obj));
1559 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, MODEST_MSG_EDIT_WINDOW (obj));
1561 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1563 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1565 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1566 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1567 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1568 priv->update_caption_visibility = TRUE;
1570 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1572 /* Track account-removed signal, this window should be closed
1573 in the case we're creating a mail associated to the account
1575 priv->account_removed_handler_id =
1576 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1578 G_CALLBACK(on_account_removed),
1581 return (ModestWindow*) obj;
1585 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1587 GString **string_buffer = (GString **) user_data;
1589 *string_buffer = g_string_append (*string_buffer, buffer);
1595 * @result: A new string which should be freed with g_free().
1598 get_formatted_data (ModestMsgEditWindow *edit_window)
1600 ModestMsgEditWindowPrivate *priv;
1601 GString *string_buffer = g_string_new ("");
1603 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1605 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1607 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1609 return g_string_free (string_buffer, FALSE);
1614 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1617 const gchar *account_name;
1618 ModestMsgEditWindowPrivate *priv;
1619 TnyIterator *att_iter;
1621 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1623 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1625 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1626 g_return_val_if_fail (account_name, NULL);
1629 /* don't free these (except from) */
1630 data = g_slice_new0 (MsgData);
1631 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1633 data->account_name = g_strdup (account_name);
1634 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1635 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1636 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1637 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1638 if (priv->draft_msg) {
1639 data->draft_msg = g_object_ref (priv->draft_msg);
1640 } else if (priv->outbox_msg) {
1641 data->draft_msg = g_object_ref (priv->outbox_msg);
1643 data->draft_msg = NULL;
1646 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1648 gtk_text_buffer_get_bounds (buf, &b, &e);
1649 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1651 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1652 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1654 data->html_body = NULL;
1656 /* deep-copy the data */
1657 att_iter = tny_list_create_iterator (priv->attachments);
1658 data->attachments = NULL;
1659 while (!tny_iterator_is_done (att_iter)) {
1660 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1661 if (!(TNY_IS_MIME_PART(part))) {
1662 g_warning ("strange data in attachment list");
1663 g_object_unref (part);
1664 tny_iterator_next (att_iter);
1667 data->attachments = g_list_append (data->attachments,
1669 tny_iterator_next (att_iter);
1671 g_object_unref (att_iter);
1673 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1674 att_iter = tny_list_create_iterator (priv->images);
1675 data->images = NULL;
1676 while (!tny_iterator_is_done (att_iter)) {
1677 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1679 if (!(TNY_IS_MIME_PART(part))) {
1680 g_warning ("strange data in attachment list");
1681 g_object_unref (part);
1682 tny_iterator_next (att_iter);
1685 cid = tny_mime_part_get_content_id (part);
1687 gchar *image_tag_id;
1688 GtkTextTag *image_tag;
1690 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1691 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1692 g_free (image_tag_id);
1694 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1696 ((gtk_text_iter_has_tag (&iter, image_tag))||
1697 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1698 data->images = g_list_append (data->images,
1699 g_object_ref (part));
1701 g_object_unref (part);
1702 tny_iterator_next (att_iter);
1704 g_object_unref (att_iter);
1706 data->priority_flags = priv->priority_flags;
1713 unref_gobject (GObject *obj, gpointer data)
1715 if (!G_IS_OBJECT(obj))
1717 g_object_unref (obj);
1721 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1724 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1732 g_free (data->from);
1733 g_free (data->subject);
1734 g_free (data->plain_body);
1735 g_free (data->html_body);
1736 g_free (data->account_name);
1738 if (data->draft_msg != NULL) {
1739 g_object_unref (data->draft_msg);
1740 data->draft_msg = NULL;
1743 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1744 g_list_free (data->attachments);
1745 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1746 g_list_free (data->images);
1748 g_slice_free (MsgData, data);
1752 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1754 guint64 *parts_size)
1756 ModestMsgEditWindowPrivate *priv;
1758 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1760 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1762 /* TODO: add images */
1763 *parts_size += priv->images_size;
1764 *parts_count += priv->images_count;
1769 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1772 ModestMsgEditWindowPrivate *priv = NULL;
1773 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1775 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1777 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1779 return MODEST_MSG_EDIT_FORMAT_HTML;
1781 return MODEST_MSG_EDIT_FORMAT_TEXT;
1785 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1786 ModestMsgEditFormat format)
1788 ModestMsgEditWindowPrivate *priv;
1790 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1791 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1794 case MODEST_MSG_EDIT_FORMAT_HTML:
1795 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1797 case MODEST_MSG_EDIT_FORMAT_TEXT:
1798 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1801 g_return_if_reached ();
1805 ModestMsgEditFormatState *
1806 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1808 ModestMsgEditFormatState *format_state = NULL;
1809 ModestMsgEditWindowPrivate *priv;
1810 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1812 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1813 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1815 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1817 format_state = g_new0 (ModestMsgEditFormatState, 1);
1818 format_state->bold = buffer_format->bold&0x1;
1819 format_state->italics = buffer_format->italic&0x1;
1820 format_state->bullet = buffer_format->bullet&0x1;
1821 format_state->color = buffer_format->color;
1822 format_state->font_size = buffer_format->font_size;
1823 format_state->font_family = wp_get_font_name (buffer_format->font);
1824 format_state->justification = buffer_format->justification;
1825 g_free (buffer_format);
1827 return format_state;
1832 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1833 const ModestMsgEditFormatState *format_state)
1835 ModestMsgEditWindowPrivate *priv;
1836 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1837 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1838 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1839 g_return_if_fail (format_state != NULL);
1841 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1842 gtk_widget_grab_focus (priv->msg_body);
1843 buffer_format->bold = (format_state->bold != FALSE);
1844 buffer_format->italic = (format_state->italics != FALSE);
1845 buffer_format->color = format_state->color;
1846 buffer_format->font_size = format_state->font_size;
1847 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1848 buffer_format->justification = format_state->justification;
1849 buffer_format->bullet = format_state->bullet;
1851 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1853 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1854 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1855 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1856 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1857 buffer_format->cs.font = (buffer_format->font != current_format->font);
1858 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1859 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1861 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1862 if (buffer_format->cs.bold) {
1863 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1864 GINT_TO_POINTER (buffer_format->bold&0x1));
1866 if (buffer_format->cs.italic) {
1867 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1868 GINT_TO_POINTER (buffer_format->italic&0x1));
1870 if (buffer_format->cs.color) {
1871 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1872 GINT_TO_POINTER (&(buffer_format->color)));
1874 if (buffer_format->cs.font_size) {
1875 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1876 GINT_TO_POINTER (buffer_format->font_size));
1878 if (buffer_format->cs.justification) {
1879 switch (buffer_format->justification) {
1880 case GTK_JUSTIFY_LEFT:
1881 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1882 GINT_TO_POINTER(TRUE));
1884 case GTK_JUSTIFY_CENTER:
1885 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1886 GINT_TO_POINTER(TRUE));
1888 case GTK_JUSTIFY_RIGHT:
1889 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1890 GINT_TO_POINTER(TRUE));
1897 if (buffer_format->cs.font) {
1898 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1899 GINT_TO_POINTER (buffer_format->font));
1901 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1902 if (buffer_format->cs.bullet) {
1903 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
1904 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
1906 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1908 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
1910 g_free (current_format);
1915 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1917 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1919 ModestWindowPrivate *parent_priv;
1920 ModestMsgEditWindowPrivate *priv;
1921 GtkWidget *new_size_menuitem;
1922 GtkWidget *new_font_menuitem;
1924 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1925 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1927 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1928 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1929 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1930 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1932 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1933 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1934 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1937 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1939 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1940 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1942 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1943 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1945 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
1946 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
1949 switch (buffer_format->justification)
1951 case GTK_JUSTIFY_LEFT:
1952 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentLeftMenu");
1954 case GTK_JUSTIFY_CENTER:
1955 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentCenterMenu");
1957 case GTK_JUSTIFY_RIGHT:
1958 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentRightMenu");
1965 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1967 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1968 G_CALLBACK (modest_msg_edit_window_color_button_change),
1970 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1971 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1972 G_CALLBACK (modest_msg_edit_window_color_button_change),
1975 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1976 buffer_format->font_size))->data);
1977 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1981 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1982 markup = g_strconcat ("<span font_family='Sans'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1983 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1985 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1986 G_CALLBACK (modest_msg_edit_window_size_change),
1988 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1989 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1990 G_CALLBACK (modest_msg_edit_window_size_change),
1994 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1995 buffer_format->font))->data);
1996 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
2000 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
2001 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2002 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2004 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
2005 G_CALLBACK (modest_msg_edit_window_font_change),
2007 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
2008 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
2009 G_CALLBACK (modest_msg_edit_window_font_change),
2013 g_free (buffer_format);
2017 #ifdef MODEST_HILDON_VERSION_0
2019 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2022 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2023 ModestMsgEditWindowPrivate *priv;
2024 GtkWidget *dialog = NULL;
2026 GdkColor *new_color = NULL;
2028 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2029 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2031 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2032 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2033 g_free (buffer_format);
2035 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2036 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2037 if (new_color != NULL) {
2038 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2039 (gpointer) new_color);
2042 gtk_widget_destroy (dialog);
2047 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2050 ModestMsgEditWindowPrivate *priv;
2051 GtkWidget *dialog = NULL;
2053 GdkColor *old_color = NULL;
2054 const GdkColor *new_color = NULL;
2056 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2057 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2059 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2060 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2062 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2063 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2064 if (new_color != NULL)
2065 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2067 gtk_widget_destroy (dialog);
2073 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2076 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2077 ModestMsgEditWindowPrivate *priv;
2078 GtkWidget *dialog = NULL;
2080 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2081 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2083 dialog = hildon_color_chooser_new ();
2084 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2085 g_free (buffer_format);
2087 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2089 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2090 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2093 gtk_widget_destroy (dialog);
2098 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2101 ModestMsgEditWindowPrivate *priv;
2102 GtkWidget *dialog = NULL;
2103 GdkColor *old_color = NULL;
2105 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2106 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2108 dialog = hildon_color_chooser_new ();
2109 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2111 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2113 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2114 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2116 gtk_widget_destroy (dialog);
2119 #endif /*!MODEST_HILDON_VERSION_0*/
2123 static TnyStream* create_stream_for_uri (const gchar* uri)
2128 TnyStream *result = NULL;
2130 GnomeVFSHandle *handle = NULL;
2131 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2132 if (test == GNOME_VFS_OK) {
2133 /* Create the tinymail stream: */
2134 /* Presumably tinymai will call gnome_vfs_close (handle) later. */
2135 result = TNY_STREAM (tny_vfs_stream_new (handle));
2142 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2145 ModestMsgEditWindowPrivate *priv;
2146 GtkWidget *dialog = NULL;
2148 GSList *uris = NULL;
2149 GSList *uri_node = NULL;
2151 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2153 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2154 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2155 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2157 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2159 response = gtk_dialog_run (GTK_DIALOG (dialog));
2161 case GTK_RESPONSE_OK:
2162 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2167 gtk_widget_destroy (dialog);
2169 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2171 GnomeVFSHandle *handle = NULL;
2172 GnomeVFSResult result;
2173 GtkTextIter position;
2174 GtkTextMark *insert_mark;
2176 uri = (const gchar *) uri_node->data;
2177 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2178 if (result == GNOME_VFS_OK) {
2180 GnomeVFSFileInfo *info;
2181 gchar *filename, *basename, *escaped_filename;
2182 TnyMimePart *mime_part;
2184 const gchar *mime_type = NULL;
2185 GnomeVFSURI *vfs_uri;
2186 guint64 stream_size;
2188 vfs_uri = gnome_vfs_uri_new (uri);
2190 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2191 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2192 g_free (escaped_filename);
2193 gnome_vfs_uri_unref (vfs_uri);
2194 info = gnome_vfs_file_info_new ();
2196 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2197 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2199 mime_type = gnome_vfs_file_info_get_mime_type (info);
2201 mime_part = tny_platform_factory_new_mime_part
2202 (modest_runtime_get_platform_factory ());
2204 TnyStream *stream = create_stream_for_uri (uri);
2205 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2207 content_id = g_strdup_printf ("%d", priv->last_cid);
2208 tny_mime_part_set_content_id (mime_part, content_id);
2209 g_free (content_id);
2212 basename = g_path_get_basename (filename);
2213 tny_mime_part_set_filename (mime_part, basename);
2216 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
2218 if (pixbuf != NULL) {
2219 priv->images_size += stream_size;
2220 priv->images_count ++;
2221 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2222 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2223 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
2226 tny_list_prepend (priv->images, (GObject *) mime_part);
2227 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2229 g_object_unref (mime_part);
2230 gnome_vfs_file_info_unref (info);
2239 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2241 GtkWidget *dialog = NULL;
2243 GSList *uris = NULL;
2246 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2247 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2248 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2250 response = gtk_dialog_run (GTK_DIALOG (dialog));
2252 case GTK_RESPONSE_OK:
2253 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2258 gtk_widget_destroy (dialog);
2260 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2261 const gchar *uri = (const gchar *) uri_node->data;
2262 modest_msg_edit_window_attach_file_one (window, uri);
2264 g_slist_foreach (uris, (GFunc) g_free, NULL);
2265 g_slist_free (uris);
2269 modest_msg_edit_window_attach_file_one (
2270 ModestMsgEditWindow *window,
2273 GnomeVFSHandle *handle = NULL;
2274 ModestMsgEditWindowPrivate *priv;
2275 GnomeVFSResult result;
2277 g_return_if_fail (window);
2278 g_return_if_fail (uri);
2280 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2282 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2283 if (result == GNOME_VFS_OK) {
2284 TnyMimePart *mime_part;
2286 const gchar *mime_type = NULL;
2288 gchar *escaped_filename;
2291 GnomeVFSFileInfo *info;
2292 GnomeVFSURI *vfs_uri;
2294 vfs_uri = gnome_vfs_uri_new (uri);
2297 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2298 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2299 g_free (escaped_filename);
2300 gnome_vfs_uri_unref (vfs_uri);
2302 info = gnome_vfs_file_info_new ();
2304 if (gnome_vfs_get_file_info (uri,
2306 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2308 mime_type = gnome_vfs_file_info_get_mime_type (info);
2309 mime_part = tny_platform_factory_new_mime_part
2310 (modest_runtime_get_platform_factory ());
2311 stream = TNY_STREAM (tny_vfs_stream_new (handle));
2313 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2315 g_object_unref (stream);
2317 content_id = g_strdup_printf ("%d", priv->last_cid);
2318 tny_mime_part_set_content_id (mime_part, content_id);
2319 g_free (content_id);
2322 basename = g_path_get_basename (filename);
2323 tny_mime_part_set_filename (mime_part, basename);
2326 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2327 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2329 info->size == 0, info->size);
2330 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2331 gtk_widget_show_all (priv->attachments_caption);
2332 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2334 g_object_unref (mime_part);
2335 gnome_vfs_file_info_unref (info);
2340 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2343 ModestMsgEditWindowPrivate *priv;
2346 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2347 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2349 if (att_list == NULL) {
2350 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2352 g_object_ref (att_list);
2355 if (tny_list_get_length (att_list) == 0) {
2356 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2358 GtkWidget *confirmation_dialog = NULL;
2359 gboolean dialog_response;
2360 gchar *message = NULL;
2361 gchar *filename = NULL;
2363 if (tny_list_get_length (att_list) == 1) {
2365 iter = tny_list_create_iterator (att_list);
2366 part = (TnyMimePart *) tny_iterator_get_current (iter);
2367 g_object_unref (iter);
2368 if (TNY_IS_MSG (part)) {
2369 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2371 filename = g_strdup (tny_header_get_subject (header));
2372 g_object_unref (header);
2374 if (filename == NULL) {
2375 filename = g_strdup (_("mail_va_no_subject"));
2378 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2380 g_object_unref (part);
2382 filename = g_strdup ("");
2384 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
2385 (tny_list_get_length (att_list) == 1)), filename);
2387 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
2389 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
2390 gtk_widget_destroy (confirmation_dialog);
2391 if (!dialog_response) {
2392 g_object_unref (att_list);
2395 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
2397 for (iter = tny_list_create_iterator (att_list);
2398 !tny_iterator_is_done (iter);
2399 tny_iterator_next (iter)) {
2400 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2401 const gchar *att_id;
2402 tny_list_remove (priv->attachments, (GObject *) mime_part);
2404 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2406 if (tny_list_get_length (priv->attachments) == 0)
2407 gtk_widget_hide (priv->attachments_caption);
2408 att_id = tny_mime_part_get_content_id (mime_part);
2410 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2412 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2413 g_object_unref (mime_part);
2415 g_object_unref (iter);
2418 g_object_unref (att_list);
2420 /* if the last attachment has been removed, focus the Subject: field */
2421 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2422 gtk_widget_grab_focus (priv->subject_field);
2426 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2429 ModestMsgEditWindowPrivate *priv;
2430 GdkColor *new_color;
2431 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2433 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2434 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2437 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2439 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2441 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2443 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2448 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
2451 ModestMsgEditWindowPrivate *priv;
2452 gint new_size_index;
2453 ModestMsgEditWindow *window;
2456 window = MODEST_MSG_EDIT_WINDOW (userdata);
2457 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2458 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2460 if (gtk_check_menu_item_get_active (menu_item)) {
2462 WPTextBufferFormat format;
2464 memset (&format, 0, sizeof (format));
2465 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2467 label = gtk_bin_get_child (GTK_BIN (menu_item));
2469 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
2470 format.cs.font_size = TRUE;
2471 format.cs.text_position = TRUE;
2472 format.cs.font = TRUE;
2473 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
2474 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2476 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2477 GINT_TO_POINTER (wp_get_font_size_index (new_size_index, 12))))
2478 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2480 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2481 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
2482 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2488 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
2491 ModestMsgEditWindowPrivate *priv;
2492 gint new_font_index;
2493 ModestMsgEditWindow *window;
2496 window = MODEST_MSG_EDIT_WINDOW (userdata);
2497 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2498 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2500 if (gtk_check_menu_item_get_active (menu_item)) {
2503 label = gtk_bin_get_child (GTK_BIN (menu_item));
2505 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
2507 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2508 GINT_TO_POINTER(new_font_index)))
2509 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2511 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2512 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2513 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2519 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
2521 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
2522 ModestWindowPrivate *parent_priv;
2523 ModestWindowMgr *mgr;
2524 gboolean is_fullscreen;
2525 GtkAction *fs_toggle_action;
2528 mgr = modest_runtime_get_window_mgr ();
2529 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
2531 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
2533 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2534 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2535 if (is_fullscreen != active)
2536 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2544 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2547 ModestMsgEditWindowPrivate *priv = NULL;
2548 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2550 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2551 if (!priv->update_caption_visibility)
2554 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2556 gtk_widget_show (priv->cc_caption);
2558 gtk_widget_hide (priv->cc_caption);
2560 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2564 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2567 ModestMsgEditWindowPrivate *priv = NULL;
2568 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2570 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2571 if (!priv->update_caption_visibility)
2574 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2576 gtk_widget_show (priv->bcc_caption);
2578 gtk_widget_hide (priv->bcc_caption);
2580 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2584 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2585 ModestRecptEditor *editor)
2587 ModestMsgEditWindowPrivate *priv;
2589 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2590 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2591 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2593 if (editor == NULL) {
2594 GtkWidget *view_focus;
2595 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2597 /* This code should be kept in sync with ModestRecptEditor. The
2598 textview inside the recpt editor is the one that really gets the
2599 focus. As it's inside a scrolled window, and this one inside the
2600 hbox recpt editor inherits from, we'll need to go up in the
2601 hierarchy to know if the text view is part of the recpt editor
2602 or if it's a different text entry */
2604 if (gtk_widget_get_parent (view_focus)) {
2605 GtkWidget *first_parent;
2607 first_parent = gtk_widget_get_parent (view_focus);
2608 if (gtk_widget_get_parent (first_parent) &&
2609 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2610 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2615 editor = MODEST_RECPT_EDITOR (priv->to_field);
2619 modest_address_book_select_addresses (editor);
2624 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2626 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2628 modest_msg_edit_window_open_addressbook (window, NULL);
2632 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2633 gboolean show_toolbar)
2635 ModestWindowPrivate *parent_priv;
2636 const gchar *action_name;
2639 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2640 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2642 /* We can not just use the code of
2643 modest_msg_edit_window_setup_toolbar because it has a
2644 mixture of both initialization and creation code. */
2646 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2648 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2650 /* Update also the actions (to update the toggles in the
2651 menus), we have to do it manually because some other window
2652 of the same time could have changed it (remember that the
2653 toolbar fullscreen mode is shared by all the windows of the
2655 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
2656 action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarFullScreenMenu";
2658 action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarNormalScreenMenu";
2660 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
2661 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
2667 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2668 TnyHeaderFlags priority_flags)
2670 ModestMsgEditWindowPrivate *priv;
2671 ModestWindowPrivate *parent_priv;
2673 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2675 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2676 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2678 if (priv->priority_flags != priority_flags) {
2679 GtkAction *priority_action = NULL;
2681 priv->priority_flags = priority_flags;
2683 switch (priority_flags) {
2684 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2685 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2686 gtk_widget_show (priv->priority_icon);
2687 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2688 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2690 case TNY_HEADER_FLAG_LOW_PRIORITY:
2691 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2692 gtk_widget_show (priv->priority_icon);
2693 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2694 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2697 gtk_widget_hide (priv->priority_icon);
2698 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2699 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2702 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2703 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2708 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2711 ModestMsgEditWindowPrivate *priv;
2712 ModestWindowPrivate *parent_priv;
2713 gint current_format;
2715 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2717 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2718 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2720 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2721 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2723 if (current_format != file_format) {
2724 switch (file_format) {
2725 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2726 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2727 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
2729 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2733 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2734 response = gtk_dialog_run (GTK_DIALOG (dialog));
2735 gtk_widget_destroy (dialog);
2736 if (response == GTK_RESPONSE_OK) {
2737 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2739 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2740 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
2745 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2750 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2753 ModestMsgEditWindowPrivate *priv;
2754 WPTextBufferFormat oldfmt, fmt;
2755 gint old_position = 0;
2759 GdkColor *color = NULL;
2760 gboolean bold, bold_set, italic, italic_set;
2761 gboolean underline, underline_set;
2762 gboolean strikethrough, strikethrough_set;
2763 gboolean position_set;
2764 gboolean font_size_set, font_set, color_set;
2767 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2768 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2770 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2772 /* First we get the currently selected font information */
2773 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2775 switch (oldfmt.text_position) {
2776 case TEXT_POSITION_NORMAL:
2779 case TEXT_POSITION_SUPERSCRIPT:
2787 g_object_set (G_OBJECT (dialog),
2788 "bold", oldfmt.bold != FALSE,
2789 "bold-set", !oldfmt.cs.bold,
2790 "underline", oldfmt.underline != FALSE,
2791 "underline-set", !oldfmt.cs.underline,
2792 "italic", oldfmt.italic != FALSE,
2793 "italic-set", !oldfmt.cs.italic,
2794 "strikethrough", oldfmt.strikethrough != FALSE,
2795 "strikethrough-set", !oldfmt.cs.strikethrough,
2796 "color", &oldfmt.color,
2797 "color-set", !oldfmt.cs.color,
2798 "size", wp_font_size[oldfmt.font_size],
2799 "size-set", !oldfmt.cs.font_size,
2800 "position", old_position,
2801 "position-set", !oldfmt.cs.text_position,
2802 "family", wp_get_font_name (oldfmt.font),
2803 "family-set", !oldfmt.cs.font,
2806 gtk_widget_show_all (dialog);
2807 response = gtk_dialog_run (GTK_DIALOG (dialog));
2808 if (response == GTK_RESPONSE_OK) {
2810 g_object_get( dialog,
2812 "bold-set", &bold_set,
2813 "underline", &underline,
2814 "underline-set", &underline_set,
2816 "italic-set", &italic_set,
2817 "strikethrough", &strikethrough,
2818 "strikethrough-set", &strikethrough_set,
2820 "color-set", &color_set,
2822 "size-set", &font_size_set,
2823 "family", &font_name,
2824 "family-set", &font_set,
2825 "position", &position,
2826 "position-set", &position_set,
2831 if (response == GTK_RESPONSE_OK) {
2832 memset(&fmt, 0, sizeof(fmt));
2838 fmt.italic = italic;
2839 fmt.cs.italic = TRUE;
2841 if (underline_set) {
2842 fmt.underline = underline;
2843 fmt.cs.underline = TRUE;
2845 if (strikethrough_set) {
2846 fmt.strikethrough = strikethrough;
2847 fmt.cs.strikethrough = TRUE;
2852 ? TEXT_POSITION_NORMAL
2853 : ( ( position == 1 )
2854 ? TEXT_POSITION_SUPERSCRIPT
2855 : TEXT_POSITION_SUBSCRIPT );
2856 fmt.cs.text_position = TRUE;
2857 fmt.font_size = oldfmt.font_size;
2861 fmt.cs.color = TRUE;
2864 fmt.font = wp_get_font_index(font_name,
2869 if (font_size_set) {
2870 fmt.cs.font_size = TRUE;
2871 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
2873 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2874 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2876 gtk_widget_destroy (dialog);
2878 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2882 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2884 ModestMsgEditWindowPrivate *priv;
2886 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2887 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2889 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2891 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2892 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2897 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2899 ModestMsgEditWindowPrivate *priv;
2901 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2902 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2904 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2906 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2907 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2912 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2914 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2916 priv->can_undo = can_undo;
2920 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2922 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2924 priv->can_redo = can_redo;
2928 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
2930 ModestMsgEditWindowPrivate *priv;
2931 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2932 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2934 return priv->can_undo;
2938 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
2940 ModestMsgEditWindowPrivate *priv;
2941 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2942 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2944 return priv->can_redo;
2949 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2952 GtkTextIter match_start, match_end;
2954 if (image_id == NULL)
2957 gtk_text_buffer_get_start_iter (buffer, &iter);
2959 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2960 GSList *tags = gtk_text_iter_get_tags (&match_start);
2962 for (node = tags; node != NULL; node = g_slist_next (node)) {
2963 GtkTextTag *tag = (GtkTextTag *) node->data;
2964 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2965 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2966 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2968 offset = gtk_text_iter_get_offset (&match_start);
2969 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2970 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2974 gtk_text_iter_forward_char (&iter);
2979 message_is_empty (ModestMsgEditWindow *window)
2981 ModestMsgEditWindowPrivate *priv = NULL;
2983 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2984 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2986 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
2987 * so we can ignore markup.
2989 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
2992 count = gtk_text_buffer_get_char_count (buf);
2998 msg_body_focus (GtkWidget *focus,
2999 GdkEventFocus *event,
3003 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3004 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3005 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3010 recpt_field_changed (GtkTextBuffer *buffer,
3011 ModestMsgEditWindow *editor)
3013 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3014 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3018 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3020 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3021 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3025 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3028 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3029 GtkTextBuffer *buffer;
3031 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3032 gtk_text_buffer_set_modified (buffer, modified);
3033 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3034 gtk_text_buffer_set_modified (buffer, modified);
3035 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3036 gtk_text_buffer_set_modified (buffer, modified);
3037 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3041 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3043 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3044 const char *account_name;
3045 GtkTextBuffer *buffer;
3047 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3048 if (gtk_text_buffer_get_modified (buffer))
3050 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3051 if (gtk_text_buffer_get_modified (buffer))
3053 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3054 if (gtk_text_buffer_get_modified (buffer))
3056 if (gtk_text_buffer_get_modified (priv->text_buffer))
3058 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
3059 if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3070 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3072 ModestMsgEditWindowPrivate *priv = NULL;
3074 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3075 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3077 /* check if there's no recipient added */
3078 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3079 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3080 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3081 /* no recipient contents, then select contacts */
3082 modest_msg_edit_window_open_addressbook (window, NULL);
3086 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3087 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3090 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3091 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3094 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3095 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3099 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3100 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3101 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3108 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3109 ModestMsgEditWindow *window)
3111 modest_msg_edit_window_offer_attach_file (window);
3115 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3117 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3119 return priv->clipboard_text;
3123 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3125 ModestMsgEditWindow *window)
3127 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3128 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3130 if (!GTK_WIDGET_VISIBLE (window))
3133 text = gtk_clipboard_wait_for_text (selection_clipboard);
3135 if (priv->clipboard_text != NULL) {
3136 g_free (priv->clipboard_text);
3138 priv->clipboard_text = text;
3140 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3143 subject_field_move_cursor (GtkEntry *entry,
3144 GtkMovementStep step,
3149 if (!GTK_WIDGET_VISIBLE (window))
3152 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3156 update_window_title (ModestMsgEditWindow *window)
3158 ModestMsgEditWindowPrivate *priv = NULL;
3159 const gchar *subject;
3161 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3162 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3163 if (subject == NULL || subject[0] == '\0')
3164 subject = _("mail_va_new_email");
3166 gtk_window_set_title (GTK_WINDOW (window), subject);
3171 subject_field_changed (GtkEditable *editable,
3172 ModestMsgEditWindow *window)
3174 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3175 update_window_title (window);
3176 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3177 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3178 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3182 subject_field_insert_text (GtkEditable *editable,
3184 gint new_text_length,
3186 ModestMsgEditWindow *window)
3188 GString *result = g_string_new ("");
3190 gint result_len = 0;
3191 const gchar *entry_text = NULL;
3194 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3195 old_length = g_utf8_strlen (entry_text, -1);
3197 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3198 gunichar c = g_utf8_get_char_validated (current, 8);
3199 /* Invalid unichar, stop */
3205 result = g_string_append_unichar (result, c);
3209 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3210 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3213 /* Prevent endless recursion */
3214 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3215 g_signal_emit_by_name (editable, "insert-text",
3216 (gpointer) result->str, (gpointer) result->len,
3217 (gpointer) position, (gpointer) window);
3218 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3222 if (result_len + old_length > 1000) {
3223 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3224 dgettext("hildon-common-strings",
3225 "ckdg_ib_maximum_characters_reached"));
3228 g_string_free (result, TRUE);
3232 text_buffer_insert_text (GtkTextBuffer *buffer,
3235 gint new_text_length,
3236 ModestMsgEditWindow *window)
3238 GString *result = g_string_new ("");
3240 gint result_len = 0;
3241 gboolean changed = FALSE;
3243 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3244 gunichar c = g_utf8_get_char_validated (current, 8);
3245 /* Invalid unichar, stop */
3251 result = g_string_append_c (result, ' ');
3255 result = g_string_append_unichar (result, c);
3261 g_signal_stop_emission_by_name (G_OBJECT (buffer), "insert-text");
3262 g_signal_handlers_block_by_func(G_OBJECT(buffer), G_CALLBACK(text_buffer_insert_text), window);
3263 g_signal_emit_by_name (buffer, "insert-text",
3265 (gpointer) result->str, (gpointer) result->len,
3267 g_signal_handlers_unblock_by_func(G_OBJECT(buffer), G_CALLBACK(text_buffer_insert_text), window);
3270 g_string_free (result, TRUE);
3274 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3277 ModestMsgEditWindowPrivate *priv = NULL;
3279 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3280 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3282 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3285 gtk_widget_show_all (priv->find_toolbar);
3286 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3288 gtk_widget_hide_all (priv->find_toolbar);
3289 gtk_widget_grab_focus (priv->msg_body);
3295 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3297 GtkTextIter *match_start,
3298 GtkTextIter *match_end)
3300 GtkTextIter end_iter;
3301 gchar *str_casefold;
3304 gchar *range_casefold;
3307 gboolean result = FALSE;
3314 gtk_text_iter_forward_to_end (&end_iter);
3316 str_casefold = g_utf8_casefold (str, -1);
3317 str_chars_n = strlen (str);
3319 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3320 range_casefold = g_utf8_casefold (range_text, -1);
3321 range_chars_n = strlen (range_casefold);
3323 if (range_chars_n < str_chars_n) {
3324 g_free (str_casefold);
3325 g_free (range_text);
3326 g_free (range_casefold);
3330 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3331 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3332 if (!g_utf8_collate (range_subtext, str_casefold)) {
3333 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3335 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3336 match_start, match_end, NULL);
3337 g_free (found_text);
3339 g_free (range_subtext);
3343 g_free (str_casefold);
3344 g_free (range_text);
3345 g_free (range_casefold);
3352 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3353 ModestMsgEditWindow *window)
3355 gchar *current_search = NULL;
3356 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3358 GtkTextIter selection_start, selection_end;
3359 GtkTextIter match_start, match_end;
3360 gboolean continue_search = FALSE;
3362 if (message_is_empty (window)) {
3363 g_free (priv->last_search);
3364 priv->last_search = NULL;
3365 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3369 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3370 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3371 g_free (current_search);
3372 g_free (priv->last_search);
3373 priv->last_search = NULL;
3374 /* Information banner about empty search */
3375 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
3379 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3380 continue_search = TRUE;
3382 g_free (priv->last_search);
3383 priv->last_search = g_strdup (current_search);
3386 if (continue_search) {
3387 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3388 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3389 &match_start, &match_end);
3391 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
3393 GtkTextIter buffer_start;
3394 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3395 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3396 &match_start, &match_end);
3398 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
3401 /* Mark as selected the string found in search */
3403 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3404 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3405 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3407 g_free (priv->last_search);
3408 priv->last_search = NULL;
3410 g_free (current_search);
3414 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3415 ModestMsgEditWindow *window)
3417 GtkToggleAction *toggle;
3418 ModestWindowPrivate *parent_priv;
3419 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3421 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
3422 gtk_toggle_action_set_active (toggle, FALSE);
3426 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3428 ModestMsgEditWindowPrivate *priv;
3430 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3435 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3438 ModestMsgEditWindowPrivate *priv;
3440 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3446 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3449 ModestMsgEditWindowPrivate *priv;
3450 TnyHeader *header = NULL;
3452 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3453 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3455 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3456 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3458 if (priv->draft_msg != NULL) {
3459 g_object_unref (priv->draft_msg);
3462 if (draft != NULL) {
3463 g_object_ref (draft);
3464 header = tny_msg_get_header (draft);
3465 if (priv->msg_uid) {
3466 g_free (priv->msg_uid);
3467 priv->msg_uid = NULL;
3469 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3470 if (GTK_WIDGET_REALIZED (window))
3471 modest_window_mgr_register_window (mgr, MODEST_WINDOW (window));
3474 priv->draft_msg = draft;
3478 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3479 GtkTextIter *start, GtkTextIter *end,
3482 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3483 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3486 if (tag == NULL+13) return;
3487 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3488 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3489 replace_with_images (window, priv->images);
3494 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3497 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3499 g_return_if_fail (TNY_IS_MIME_PART (part));
3500 tny_list_prepend (priv->attachments, (GObject *) part);
3501 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3502 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3503 gtk_widget_show_all (priv->attachments_caption);
3504 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3508 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3510 ModestMsgEditWindowPrivate *priv;
3512 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3513 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3515 return priv->msg_uid;
3519 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3520 ModestMsgEditWindowWidgetType widget_type)
3522 ModestMsgEditWindowPrivate *priv;
3524 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3525 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3527 switch (widget_type) {
3528 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3529 return priv->msg_body;
3531 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3532 return priv->to_field;
3534 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3535 return priv->cc_field;
3537 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3538 return priv->bcc_field;
3540 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3541 return priv->subject_field;
3543 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3544 return priv->attachments_view;
3552 remove_tags (WPTextBuffer *buffer)
3554 GtkTextIter start, end;
3556 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3557 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3559 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3563 on_account_removed (TnyAccountStore *account_store,
3564 TnyAccount *account,
3567 /* Do nothing if it's a store account, because we use the
3568 transport to send the messages */
3569 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3570 const gchar *parent_acc = NULL;
3571 const gchar *our_acc = NULL;
3573 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3574 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3575 /* Close this window if I'm showing a message of the removed account */
3576 if (strcmp (parent_acc, our_acc) == 0)
3577 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3582 on_zoom_minus_plus_not_implemented (ModestWindow *window)
3584 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3586 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
3592 set_zoom_do_nothing (ModestWindow *window,
3598 get_zoom_do_nothing (ModestWindow *window)