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);
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);
550 priv->scroll_drag_timeout_id = 0;
556 correct_scroll_without_drag_check (ModestMsgEditWindow *w)
558 ModestMsgEditWindowPrivate *priv;
561 GdkRectangle rectangle;
567 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
569 if (!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.75;
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);
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);
644 void vadj_changed (GtkAdjustment *adj,
645 ModestMsgEditWindow *window)
647 ModestMsgEditWindowPrivate *priv;
649 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
651 if (priv->last_upper != adj->upper) {
652 priv->last_upper = adj->upper;
653 correct_scroll (window);
658 connect_signals (ModestMsgEditWindow *obj)
660 ModestMsgEditWindowPrivate *priv;
662 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
664 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
665 G_CALLBACK (text_buffer_refresh_attributes), obj);
666 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
667 G_CALLBACK (text_buffer_can_undo), obj);
668 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
669 G_CALLBACK (text_buffer_can_redo), obj);
670 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
671 G_CALLBACK (body_changed), obj);
672 g_signal_connect (G_OBJECT (priv->text_buffer), "insert-text",
673 G_CALLBACK (text_buffer_insert_text), obj);
674 g_signal_connect (G_OBJECT (obj), "window-state-event",
675 G_CALLBACK (modest_msg_edit_window_window_state_event),
677 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
678 G_CALLBACK (text_buffer_end_user_action), obj);
679 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
680 G_CALLBACK (text_buffer_mark_set), obj);
681 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
682 G_CALLBACK (text_buffer_apply_tag), obj);
683 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
684 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
685 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
686 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
687 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
688 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
690 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
691 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
693 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
694 G_CALLBACK (msg_body_focus), obj);
695 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
696 G_CALLBACK (msg_body_focus), obj);
697 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
698 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
699 "changed", G_CALLBACK (recpt_field_changed), obj);
700 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
701 "changed", G_CALLBACK (recpt_field_changed), obj);
702 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
703 "changed", G_CALLBACK (recpt_field_changed), obj);
704 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
705 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
706 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
708 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
709 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
711 g_signal_connect (G_OBJECT (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll))),
713 G_CALLBACK (vadj_changed),
716 priv->clipboard_change_handler_id =
717 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
718 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
719 priv->default_clipboard_change_handler_id =
720 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
721 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
726 init_window (ModestMsgEditWindow *obj)
728 GtkWidget *from_caption, *to_caption, *subject_caption;
729 GtkWidget *main_vbox;
730 ModestMsgEditWindowPrivate *priv;
731 GtkActionGroup *action_group;
732 ModestWindowPrivate *parent_priv;
733 GdkPixbuf *window_icon = NULL;
734 GError *error = NULL;
736 GtkSizeGroup *size_group;
737 GtkWidget *subject_box;
738 GtkWidget *attachment_icon;
739 GtkWidget *window_box;
740 #if (GTK_MINOR_VERSION >= 10)
741 GdkAtom deserialize_type;
743 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
744 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
746 parent_priv->ui_manager = gtk_ui_manager_new();
747 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
748 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
750 /* Add common actions */
751 gtk_action_group_add_actions (action_group,
752 modest_msg_edit_action_entries,
753 G_N_ELEMENTS (modest_msg_edit_action_entries),
755 gtk_action_group_add_toggle_actions (action_group,
756 modest_msg_edit_toggle_action_entries,
757 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
759 gtk_action_group_add_radio_actions (action_group,
760 modest_msg_edit_alignment_radio_action_entries,
761 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
763 G_CALLBACK (modest_ui_actions_on_change_justify),
765 gtk_action_group_add_radio_actions (action_group,
766 modest_msg_edit_priority_action_entries,
767 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
769 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
771 gtk_action_group_add_radio_actions (action_group,
772 modest_msg_edit_file_format_action_entries,
773 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
774 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
775 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
777 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
778 g_object_unref (action_group);
780 /* Load the UI definition */
781 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
784 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
785 g_clear_error (&error);
788 /* Add accelerators */
789 gtk_window_add_accel_group (GTK_WINDOW (obj),
790 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
792 parent_priv->menubar = NULL;
794 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
796 /* Note: This ModestPairList* must exist for as long as the combo
797 * that uses it, because the ModestComboBox uses the ID opaquely,
798 * so it can't know how to manage its memory. */
799 priv->from_field = modest_combo_box_new (NULL, g_str_equal);
801 priv->to_field = modest_recpt_editor_new ();
802 priv->cc_field = modest_recpt_editor_new ();
803 priv->bcc_field = modest_recpt_editor_new ();
804 subject_box = gtk_hbox_new (FALSE, 0);
805 priv->priority_icon = gtk_image_new ();
806 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
807 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
808 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
809 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
810 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
811 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
812 priv->add_attachment_button = gtk_button_new ();
813 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
814 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
815 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
816 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
817 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
818 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
819 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
820 priv->attachments_view = modest_attachments_view_new (NULL);
822 priv->header_box = gtk_vbox_new (FALSE, 0);
824 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
825 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
826 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
827 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
828 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
829 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
830 g_object_unref (size_group);
832 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
833 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
834 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
835 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
836 gtk_size_group_add_widget (size_group, priv->subject_field);
837 gtk_size_group_add_widget (size_group, priv->attachments_view);
838 g_object_unref (size_group);
840 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
841 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
842 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
843 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
844 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
845 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
846 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
849 priv->msg_body = wp_text_view_new ();
850 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
851 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
852 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
853 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
854 #if (GTK_MINOR_VERSION >= 10)
855 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
856 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
858 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
859 deserialize_type, TRUE);
861 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
863 priv->find_toolbar = hildon_find_toolbar_new (NULL);
864 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
866 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
868 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
869 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
870 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
871 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->scroll), TRUE);
873 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
875 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
876 priv->frame = gtk_frame_new (NULL);
877 gtk_box_pack_start (GTK_BOX(main_vbox), priv->frame, TRUE, TRUE, 0);
879 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
880 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
881 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
883 window_box = gtk_vbox_new (FALSE, 0);
884 gtk_container_add (GTK_CONTAINER(obj), window_box);
886 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
888 gtk_container_add (GTK_CONTAINER (priv->frame), priv->msg_body);
890 /* Set window icon */
891 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
893 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
894 g_object_unref (window_icon);
899 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
901 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
903 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
904 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
905 priv->clipboard_change_handler_id))
906 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
907 priv->clipboard_change_handler_id);
908 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
909 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
910 priv->default_clipboard_change_handler_id))
911 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
912 priv->default_clipboard_change_handler_id);
914 if (priv->account_removed_handler_id &&
915 g_signal_handler_is_connected (modest_runtime_get_account_store (),
916 priv->account_removed_handler_id))
917 g_signal_handler_disconnect(modest_runtime_get_account_store (),
918 priv->account_removed_handler_id);
922 modest_msg_edit_window_finalize (GObject *obj)
924 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
926 /* Sanity check: shouldn't be needed, the window mgr should
927 call this function before */
928 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
930 if (priv->clipboard_text != NULL) {
931 g_free (priv->clipboard_text);
932 priv->clipboard_text = NULL;
935 if (priv->draft_msg != NULL) {
936 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
937 if (TNY_IS_HEADER (header)) {
938 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
939 modest_window_mgr_unregister_header (mgr, header);
941 g_object_unref (priv->draft_msg);
942 priv->draft_msg = NULL;
944 if (priv->outbox_msg != NULL) {
945 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
946 if (TNY_IS_HEADER (header)) {
947 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
948 modest_window_mgr_unregister_header (mgr, header);
950 g_object_unref (priv->outbox_msg);
951 priv->outbox_msg = NULL;
953 if (priv->scroll_drag_timeout_id > 0) {
954 g_source_remove (priv->scroll_drag_timeout_id);
955 priv->scroll_drag_timeout_id = 0;
957 g_free (priv->msg_uid);
958 g_free (priv->last_search);
959 g_slist_free (priv->font_items_group);
960 g_slist_free (priv->size_items_group);
961 g_object_unref (priv->attachments);
962 g_object_unref (priv->images);
964 /* This had to stay alive for as long as the combobox that used it: */
965 modest_pair_list_free (priv->from_field_protos);
967 G_OBJECT_CLASS(parent_class)->finalize (obj);
971 pixbuf_from_stream (TnyStream *stream, const gchar *mime_type, guint64 *stream_size)
973 GdkPixbufLoader *loader;
979 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
981 if (loader == NULL) {
987 tny_stream_reset (TNY_STREAM (stream));
988 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
989 unsigned char read_buffer[128];
991 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
993 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
997 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
998 g_object_ref (pixbuf);
999 gdk_pixbuf_loader_close (loader, NULL);
1000 g_object_unref (loader);
1002 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1003 GdkPixbuf *new_pixbuf;
1005 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1006 gdk_pixbuf_get_width (pixbuf);
1007 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1008 g_object_unref (pixbuf);
1009 pixbuf = new_pixbuf;
1013 *stream_size = size;
1019 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1021 ModestMsgEditWindowPrivate *priv;
1024 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1026 for (iter = tny_list_create_iterator (attachments);
1027 !tny_iterator_is_done (iter);
1028 tny_iterator_next (iter)) {
1029 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1030 const gchar *cid = tny_mime_part_get_content_id (part);
1031 const gchar *mime_type = tny_mime_part_get_content_type (part);
1032 if ((cid != NULL)&&(mime_type != NULL)) {
1033 guint64 stream_size;
1034 TnyStream *stream = tny_mime_part_get_stream (part);
1035 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
1038 g_object_unref (stream);
1040 if (pixbuf != NULL) {
1041 priv->images_count ++;
1042 priv->images_size += stream_size;
1043 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1044 g_object_unref (pixbuf);
1047 g_object_unref (part);
1049 g_object_unref (iter);
1053 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1055 TnyMimePart *parent = NULL;
1056 const gchar *content_type = NULL;
1057 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1059 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1061 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1062 parent = g_object_ref (msg);
1063 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1064 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1067 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1068 iter = tny_list_create_iterator (parts);
1069 while (!tny_iterator_is_done (iter)) {
1071 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1072 content_type = tny_mime_part_get_content_type (part);
1073 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1077 g_object_unref (part);
1079 tny_iterator_next (iter);
1081 g_object_unref (iter);
1082 g_object_unref (parts);
1085 if (parent != NULL) {
1086 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1089 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1090 iter = tny_list_create_iterator (parts);
1091 while (!tny_iterator_is_done (iter)) {
1093 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1094 content_type = tny_mime_part_get_content_type (part);
1095 if (content_type && g_str_has_prefix (content_type, "image/")) {
1096 tny_list_prepend (priv->images, (GObject *) part);
1098 g_object_unref (part);
1099 tny_iterator_next (iter);
1101 g_object_unref (iter);
1102 g_object_unref (parts);
1103 g_object_unref (parent);
1108 update_last_cid (ModestMsgEditWindow *self, TnyList *attachments)
1111 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1113 for (iter = tny_list_create_iterator (attachments) ;
1114 !tny_iterator_is_done (iter);
1115 tny_iterator_next (iter)) {
1116 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1117 const gchar *cid = tny_mime_part_get_content_id (part);
1119 char *invalid = NULL;
1120 gint int_cid = strtol (cid, &invalid, 10);
1121 if ((invalid != NULL) && (*invalid == '\0') && (int_cid > priv->last_cid)) {
1122 priv->last_cid = int_cid;
1125 g_object_unref (part);
1127 g_object_unref (iter);
1131 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1134 const gchar *to, *cc, *bcc, *subject;
1136 ModestMsgEditWindowPrivate *priv;
1138 TnyHeaderFlags priority_flags;
1139 TnyFolder *msg_folder;
1140 gboolean is_html = FALSE;
1142 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1143 g_return_if_fail (TNY_IS_MSG (msg));
1145 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1147 header = tny_msg_get_header (msg);
1148 to = tny_header_get_to (header);
1149 cc = tny_header_get_cc (header);
1150 bcc = tny_header_get_bcc (header);
1151 subject = tny_header_get_subject (header);
1152 priority_flags = tny_header_get_priority (header);
1155 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1157 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1158 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1159 gtk_widget_show (priv->cc_caption);
1160 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1161 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1162 gtk_widget_hide (priv->cc_caption);
1165 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1166 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1167 gtk_widget_show (priv->bcc_caption);
1168 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1169 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1170 gtk_widget_hide (priv->bcc_caption);
1173 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1174 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1177 update_window_title (self);
1179 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1180 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1182 if ((body == NULL)||(body[0] == '\0')) {
1184 body = modest_text_utils_convert_to_html ("");
1187 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1188 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1191 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1194 /* Add attachments to the view */
1195 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1196 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1197 if (tny_list_get_length (priv->attachments) == 0) {
1198 gtk_widget_hide (priv->attachments_caption);
1200 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1201 gtk_widget_show_all (priv->attachments_caption);
1203 get_related_images (self, msg);
1204 update_last_cid (self, priv->attachments);
1205 update_last_cid (self, priv->images);
1206 replace_with_images (self, priv->images);
1208 if (preserve_is_rich && !is_html) {
1209 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1210 /* Get the default format required from configuration */
1211 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1212 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1215 /* Set the default focus depending on having already a To: field or not */
1216 if ((!to)||(*to == '\0')) {
1217 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1219 gtk_widget_grab_focus (priv->msg_body);
1222 /* TODO: lower priority, select in the From: combo to the
1223 value that comes from msg <- not sure, should it be
1226 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1228 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1229 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1231 modest_msg_edit_window_reset_modified (self);
1233 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1234 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1235 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1236 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1238 if (priv->msg_uid) {
1239 g_free (priv->msg_uid);
1240 priv->msg_uid = NULL;
1243 /* we should set a reference to the incoming message if it is a draft */
1244 msg_folder = tny_msg_get_folder (msg);
1246 if (modest_tny_folder_is_local_folder (msg_folder)) {
1247 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1248 if (type == TNY_FOLDER_TYPE_INVALID)
1249 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1251 if (type == TNY_FOLDER_TYPE_DRAFTS)
1252 priv->draft_msg = g_object_ref(msg);
1253 if (type == TNY_FOLDER_TYPE_OUTBOX)
1254 priv->outbox_msg = g_object_ref(msg);
1255 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1257 g_object_unref (msg_folder);
1262 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
1265 GList *item_children, *node;
1266 GtkWidget *bin_child;
1268 bin_child = gtk_bin_get_child (GTK_BIN(item));
1270 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
1272 for (node = item_children; node != NULL; node = g_list_next (node)) {
1273 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
1274 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
1277 g_list_free (item_children);
1281 menu_tool_button_dont_expand (GtkMenuToolButton *item)
1284 GList *item_children, *node;
1286 box = gtk_bin_get_child (GTK_BIN (item));
1287 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
1288 item_children = gtk_container_get_children (GTK_CONTAINER (box));
1290 for (node = item_children; node != NULL; node = g_list_next (node)) {
1291 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
1292 if (GTK_IS_TOGGLE_BUTTON (node->data))
1293 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
1294 else if (GTK_IS_BUTTON (node->data))
1295 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
1297 g_list_free (item_children);
1302 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1304 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1305 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1306 GtkWidget *placeholder;
1307 GtkWidget *tool_item;
1312 GtkWidget *sizes_menu;
1313 GtkWidget *fonts_menu;
1314 GSList *radio_group = NULL;
1315 GSList *node = NULL;
1319 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1320 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1322 /* Font color placeholder */
1323 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1324 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1327 tool_item = GTK_WIDGET (gtk_tool_item_new ());
1328 priv->font_color_button = hildon_color_button_new ();
1329 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
1330 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1331 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
1332 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1333 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1334 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1335 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1337 G_CALLBACK (modest_msg_edit_window_color_button_change),
1340 /* Font size and face placeholder */
1341 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1342 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1344 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1345 priv->size_tool_button_label = gtk_label_new (NULL);
1346 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1347 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1348 size_text,"</span>", NULL);
1349 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1351 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
1352 sizes_menu = gtk_menu_new ();
1353 priv->size_items_group = NULL;
1355 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1356 GtkWidget *size_menu_item;
1358 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1359 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
1360 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
1361 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
1362 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
1363 gtk_widget_show (size_menu_item);
1365 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
1369 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1370 GtkWidget *item = (GtkWidget *) node->data;
1371 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
1375 priv->size_items_group = g_slist_reverse (priv->size_items_group);
1376 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
1377 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1378 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1379 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1380 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1381 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1382 priv->font_size_toolitem = tool_item;
1385 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1386 priv->font_tool_button_label = gtk_label_new (NULL);
1387 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1388 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1390 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
1391 fonts_menu = gtk_menu_new ();
1392 priv->font_items_group = NULL;
1394 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1395 GtkWidget *font_menu_item;
1396 GtkWidget *child_label;
1398 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
1399 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
1400 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
1401 wp_get_font_name (font_index), "</span>", NULL);
1402 gtk_label_set_markup (GTK_LABEL (child_label), markup);
1405 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
1406 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
1407 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
1408 gtk_widget_show (font_menu_item);
1410 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
1413 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1414 GtkWidget *item = (GtkWidget *) node->data;
1415 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
1418 priv->font_items_group = g_slist_reverse (priv->font_items_group);
1419 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
1420 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1421 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1422 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1423 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1424 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1425 priv->font_face_toolitem = tool_item;
1427 /* Set expand and homogeneous for remaining items */
1428 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1429 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1430 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1431 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1432 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1433 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1434 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1435 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1436 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1438 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1439 will not show the tool items added to the placeholders) */
1440 gtk_widget_show_all (parent_priv->toolbar);
1442 /* Set the no show all *after* showing all items. We do not
1443 want the toolbar to be shown with a show all because it
1444 could go agains the gconf setting regarding showing or not
1445 the toolbar of the editor window */
1446 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1452 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean preserve_is_rich)
1455 ModestWindowPrivate *parent_priv;
1456 ModestMsgEditWindowPrivate *priv;
1457 ModestPair *account_pair = NULL;
1458 ModestDimmingRulesGroup *menu_rules_group = NULL;
1459 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1460 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1461 ModestWindowMgr *mgr = NULL;
1463 g_return_val_if_fail (msg, NULL);
1464 g_return_val_if_fail (account_name, NULL);
1466 mgr = modest_runtime_get_window_mgr ();
1468 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1470 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1471 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1473 /* Menubar. Update the state of some toggles */
1474 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1475 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
1476 priv->from_field_protos = get_transports ();
1477 modest_combo_box_set_pair_list (MODEST_COMBO_BOX (priv->from_field), priv->from_field_protos);
1478 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1479 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1482 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1484 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1486 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1488 account_pair = find_transport_from_message_sender (priv->from_field_protos, msg);
1489 if (account_pair == NULL) {
1490 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
1492 if (account_pair != NULL)
1493 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
1495 priv->original_account_name = account_pair ? (const gchar *) account_pair->first : NULL;
1497 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new ();
1498 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1499 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1500 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1501 /* Add common dimming rules */
1502 modest_dimming_rules_group_add_rules (menu_rules_group,
1503 modest_msg_edit_window_menu_dimming_entries,
1504 G_N_ELEMENTS (modest_msg_edit_window_menu_dimming_entries),
1505 MODEST_WINDOW (obj));
1506 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1507 modest_msg_edit_window_toolbar_dimming_entries,
1508 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1509 MODEST_WINDOW (obj));
1510 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_button,
1511 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1512 MODEST_WINDOW (obj));
1513 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1514 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1515 MODEST_WINDOW (obj));
1516 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1517 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1518 MODEST_WINDOW (obj));
1519 modest_dimming_rules_group_add_rules (clipboard_rules_group,
1520 modest_msg_edit_window_clipboard_dimming_entries,
1521 G_N_ELEMENTS (modest_msg_edit_window_clipboard_dimming_entries),
1522 MODEST_WINDOW (obj));
1523 /* Insert dimming rules group for this window */
1524 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1525 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1526 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1527 /* Checks the dimming rules */
1528 g_object_unref (menu_rules_group);
1529 g_object_unref (toolbar_rules_group);
1530 g_object_unref (clipboard_rules_group);
1531 gtk_widget_show_all (GTK_WIDGET (obj));
1532 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, MODEST_MSG_EDIT_WINDOW (obj));
1534 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1536 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1538 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1539 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1540 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1541 priv->update_caption_visibility = TRUE;
1543 modest_msg_edit_window_reset_modified (MODEST_MSG_EDIT_WINDOW (obj));
1545 /* Track account-removed signal, this window should be closed
1546 in the case we're creating a mail associated to the account
1548 priv->account_removed_handler_id =
1549 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1551 G_CALLBACK(on_account_removed),
1554 return (ModestWindow*) obj;
1558 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1560 GString **string_buffer = (GString **) user_data;
1562 *string_buffer = g_string_append (*string_buffer, buffer);
1568 * @result: A new string which should be freed with g_free().
1571 get_formatted_data (ModestMsgEditWindow *edit_window)
1573 ModestMsgEditWindowPrivate *priv;
1574 GString *string_buffer = g_string_new ("");
1576 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1578 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1580 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1582 return g_string_free (string_buffer, FALSE);
1587 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1590 const gchar *account_name;
1591 ModestMsgEditWindowPrivate *priv;
1592 TnyIterator *att_iter;
1594 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1596 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1598 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1599 g_return_val_if_fail (account_name, NULL);
1602 /* don't free these (except from) */
1603 data = g_slice_new0 (MsgData);
1604 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1606 data->account_name = g_strdup (account_name);
1607 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1608 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1609 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1610 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1611 if (priv->draft_msg) {
1612 data->draft_msg = g_object_ref (priv->draft_msg);
1613 } else if (priv->outbox_msg) {
1614 data->draft_msg = g_object_ref (priv->outbox_msg);
1616 data->draft_msg = NULL;
1619 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1621 gtk_text_buffer_get_bounds (buf, &b, &e);
1622 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1624 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1625 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1627 data->html_body = NULL;
1629 /* deep-copy the data */
1630 att_iter = tny_list_create_iterator (priv->attachments);
1631 data->attachments = NULL;
1632 while (!tny_iterator_is_done (att_iter)) {
1633 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1634 if (!(TNY_IS_MIME_PART(part))) {
1635 g_warning ("strange data in attachment list");
1636 g_object_unref (part);
1637 tny_iterator_next (att_iter);
1640 data->attachments = g_list_append (data->attachments,
1642 tny_iterator_next (att_iter);
1644 g_object_unref (att_iter);
1646 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1647 att_iter = tny_list_create_iterator (priv->images);
1648 data->images = NULL;
1649 while (!tny_iterator_is_done (att_iter)) {
1650 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1652 if (!(TNY_IS_MIME_PART(part))) {
1653 g_warning ("strange data in attachment list");
1654 g_object_unref (part);
1655 tny_iterator_next (att_iter);
1658 cid = tny_mime_part_get_content_id (part);
1660 gchar *image_tag_id;
1661 GtkTextTag *image_tag;
1663 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1664 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1665 g_free (image_tag_id);
1667 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1669 ((gtk_text_iter_has_tag (&iter, image_tag))||
1670 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1671 data->images = g_list_append (data->images,
1672 g_object_ref (part));
1674 g_object_unref (part);
1675 tny_iterator_next (att_iter);
1677 g_object_unref (att_iter);
1679 data->priority_flags = priv->priority_flags;
1686 unref_gobject (GObject *obj, gpointer data)
1688 if (!G_IS_OBJECT(obj))
1690 g_object_unref (obj);
1694 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1697 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1705 g_free (data->from);
1706 g_free (data->subject);
1707 g_free (data->plain_body);
1708 g_free (data->html_body);
1709 g_free (data->account_name);
1711 if (data->draft_msg != NULL) {
1712 g_object_unref (data->draft_msg);
1713 data->draft_msg = NULL;
1716 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1717 g_list_free (data->attachments);
1718 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1719 g_list_free (data->images);
1721 g_slice_free (MsgData, data);
1725 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1727 guint64 *parts_size)
1729 ModestMsgEditWindowPrivate *priv;
1731 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1733 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1735 /* TODO: add images */
1736 *parts_size += priv->images_size;
1737 *parts_count += priv->images_count;
1742 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1745 ModestMsgEditWindowPrivate *priv = NULL;
1746 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1748 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1750 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1752 return MODEST_MSG_EDIT_FORMAT_HTML;
1754 return MODEST_MSG_EDIT_FORMAT_TEXT;
1758 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1759 ModestMsgEditFormat format)
1761 ModestMsgEditWindowPrivate *priv;
1763 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1764 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1767 case MODEST_MSG_EDIT_FORMAT_HTML:
1768 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1770 case MODEST_MSG_EDIT_FORMAT_TEXT:
1771 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1774 g_return_if_reached ();
1778 ModestMsgEditFormatState *
1779 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1781 ModestMsgEditFormatState *format_state = NULL;
1782 ModestMsgEditWindowPrivate *priv;
1783 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1785 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1786 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1788 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1790 format_state = g_new0 (ModestMsgEditFormatState, 1);
1791 format_state->bold = buffer_format->bold&0x1;
1792 format_state->italics = buffer_format->italic&0x1;
1793 format_state->bullet = buffer_format->bullet&0x1;
1794 format_state->color = buffer_format->color;
1795 format_state->font_size = buffer_format->font_size;
1796 format_state->font_family = wp_get_font_name (buffer_format->font);
1797 format_state->justification = buffer_format->justification;
1798 g_free (buffer_format);
1800 return format_state;
1805 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1806 const ModestMsgEditFormatState *format_state)
1808 ModestMsgEditWindowPrivate *priv;
1809 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1810 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1811 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1812 g_return_if_fail (format_state != NULL);
1814 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1815 gtk_widget_grab_focus (priv->msg_body);
1816 buffer_format->bold = (format_state->bold != FALSE);
1817 buffer_format->italic = (format_state->italics != FALSE);
1818 buffer_format->color = format_state->color;
1819 buffer_format->font_size = format_state->font_size;
1820 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1821 buffer_format->justification = format_state->justification;
1822 buffer_format->bullet = format_state->bullet;
1824 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1826 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1827 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1828 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1829 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1830 buffer_format->cs.font = (buffer_format->font != current_format->font);
1831 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1832 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1834 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1835 if (buffer_format->cs.bold) {
1836 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1837 GINT_TO_POINTER (buffer_format->bold&0x1));
1839 if (buffer_format->cs.italic) {
1840 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1841 GINT_TO_POINTER (buffer_format->italic&0x1));
1843 if (buffer_format->cs.color) {
1844 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1845 GINT_TO_POINTER (&(buffer_format->color)));
1847 if (buffer_format->cs.font_size) {
1848 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1849 GINT_TO_POINTER (buffer_format->font_size));
1851 if (buffer_format->cs.justification) {
1852 switch (buffer_format->justification) {
1853 case GTK_JUSTIFY_LEFT:
1854 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1855 GINT_TO_POINTER(TRUE));
1857 case GTK_JUSTIFY_CENTER:
1858 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1859 GINT_TO_POINTER(TRUE));
1861 case GTK_JUSTIFY_RIGHT:
1862 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1863 GINT_TO_POINTER(TRUE));
1870 if (buffer_format->cs.font) {
1871 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1872 GINT_TO_POINTER (buffer_format->font));
1874 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1875 if (buffer_format->cs.bullet) {
1876 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
1877 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
1879 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1881 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
1883 g_free (current_format);
1888 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1890 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1892 ModestWindowPrivate *parent_priv;
1893 ModestMsgEditWindowPrivate *priv;
1894 GtkWidget *new_size_menuitem;
1895 GtkWidget *new_font_menuitem;
1897 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1898 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1900 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1901 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1902 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1903 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1905 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1906 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1907 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1910 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1912 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1913 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1915 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1916 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1918 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
1919 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
1922 switch (buffer_format->justification)
1924 case GTK_JUSTIFY_LEFT:
1925 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentLeftMenu");
1927 case GTK_JUSTIFY_CENTER:
1928 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentCenterMenu");
1930 case GTK_JUSTIFY_RIGHT:
1931 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentRightMenu");
1938 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1940 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1941 G_CALLBACK (modest_msg_edit_window_color_button_change),
1943 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1944 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1945 G_CALLBACK (modest_msg_edit_window_color_button_change),
1948 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1949 buffer_format->font_size))->data);
1950 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1954 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1955 markup = g_strconcat ("<span font_family='Sans'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1956 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1958 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1959 G_CALLBACK (modest_msg_edit_window_size_change),
1961 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1962 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1963 G_CALLBACK (modest_msg_edit_window_size_change),
1967 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1968 buffer_format->font))->data);
1969 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1973 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1974 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1975 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1977 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1978 G_CALLBACK (modest_msg_edit_window_font_change),
1980 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1981 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1982 G_CALLBACK (modest_msg_edit_window_font_change),
1986 g_free (buffer_format);
1990 #ifdef MODEST_HILDON_VERSION_0
1992 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1995 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1996 ModestMsgEditWindowPrivate *priv;
1997 GtkWidget *dialog = NULL;
1999 GdkColor *new_color = NULL;
2001 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2002 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2004 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2005 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2006 g_free (buffer_format);
2008 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2009 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2010 if (new_color != NULL) {
2011 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2012 (gpointer) new_color);
2015 gtk_widget_destroy (dialog);
2020 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2023 ModestMsgEditWindowPrivate *priv;
2024 GtkWidget *dialog = NULL;
2026 GdkColor *old_color = NULL;
2027 const GdkColor *new_color = NULL;
2029 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2030 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2032 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2033 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
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_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2040 gtk_widget_destroy (dialog);
2046 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2049 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2050 ModestMsgEditWindowPrivate *priv;
2051 GtkWidget *dialog = NULL;
2053 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2054 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2056 dialog = hildon_color_chooser_new ();
2057 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2058 g_free (buffer_format);
2060 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2062 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2063 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2066 gtk_widget_destroy (dialog);
2071 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2074 ModestMsgEditWindowPrivate *priv;
2075 GtkWidget *dialog = NULL;
2076 GdkColor *old_color = NULL;
2078 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2079 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2081 dialog = hildon_color_chooser_new ();
2082 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2084 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2086 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2087 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2089 gtk_widget_destroy (dialog);
2092 #endif /*!MODEST_HILDON_VERSION_0*/
2096 static TnyStream* create_stream_for_uri (const gchar* uri)
2101 TnyStream *result = NULL;
2103 GnomeVFSHandle *handle = NULL;
2104 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2105 if (test == GNOME_VFS_OK) {
2106 /* Create the tinymail stream: */
2107 /* Presumably tinymai will call gnome_vfs_close (handle) later. */
2108 result = TNY_STREAM (tny_vfs_stream_new (handle));
2115 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2118 ModestMsgEditWindowPrivate *priv;
2119 GtkWidget *dialog = NULL;
2121 GSList *uris = NULL;
2122 GSList *uri_node = NULL;
2124 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2126 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2127 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2128 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2130 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2132 response = gtk_dialog_run (GTK_DIALOG (dialog));
2134 case GTK_RESPONSE_OK:
2135 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2140 gtk_widget_destroy (dialog);
2142 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2144 GnomeVFSHandle *handle = NULL;
2145 GnomeVFSResult result;
2146 GtkTextIter position;
2147 GtkTextMark *insert_mark;
2149 uri = (const gchar *) uri_node->data;
2150 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2151 if (result == GNOME_VFS_OK) {
2153 GnomeVFSFileInfo *info;
2154 gchar *filename, *basename, *escaped_filename;
2155 TnyMimePart *mime_part;
2157 const gchar *mime_type = NULL;
2158 GnomeVFSURI *vfs_uri;
2159 guint64 stream_size;
2161 vfs_uri = gnome_vfs_uri_new (uri);
2163 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2164 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2165 g_free (escaped_filename);
2166 gnome_vfs_uri_unref (vfs_uri);
2167 info = gnome_vfs_file_info_new ();
2169 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2170 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2172 mime_type = gnome_vfs_file_info_get_mime_type (info);
2174 mime_part = tny_platform_factory_new_mime_part
2175 (modest_runtime_get_platform_factory ());
2177 TnyStream *stream = create_stream_for_uri (uri);
2178 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2180 content_id = g_strdup_printf ("%d", priv->last_cid);
2181 tny_mime_part_set_content_id (mime_part, content_id);
2182 g_free (content_id);
2185 basename = g_path_get_basename (filename);
2186 tny_mime_part_set_filename (mime_part, basename);
2189 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
2191 if (pixbuf != NULL) {
2192 priv->images_size += stream_size;
2193 priv->images_count ++;
2194 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2195 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2196 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
2199 tny_list_prepend (priv->images, (GObject *) mime_part);
2200 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2202 g_object_unref (mime_part);
2203 gnome_vfs_file_info_unref (info);
2212 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2214 GtkWidget *dialog = NULL;
2216 GSList *uris = NULL;
2219 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2220 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2221 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2223 response = gtk_dialog_run (GTK_DIALOG (dialog));
2225 case GTK_RESPONSE_OK:
2226 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2231 gtk_widget_destroy (dialog);
2233 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2234 const gchar *uri = (const gchar *) uri_node->data;
2235 modest_msg_edit_window_attach_file_one (window, uri);
2237 g_slist_foreach (uris, (GFunc) g_free, NULL);
2238 g_slist_free (uris);
2242 modest_msg_edit_window_attach_file_one (
2243 ModestMsgEditWindow *window,
2246 GnomeVFSHandle *handle = NULL;
2247 ModestMsgEditWindowPrivate *priv;
2248 GnomeVFSResult result;
2250 g_return_if_fail (window);
2251 g_return_if_fail (uri);
2253 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2255 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2256 if (result == GNOME_VFS_OK) {
2257 TnyMimePart *mime_part;
2259 const gchar *mime_type = NULL;
2261 gchar *escaped_filename;
2264 GnomeVFSFileInfo *info;
2265 GnomeVFSURI *vfs_uri;
2267 vfs_uri = gnome_vfs_uri_new (uri);
2270 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2271 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2272 g_free (escaped_filename);
2273 gnome_vfs_uri_unref (vfs_uri);
2275 info = gnome_vfs_file_info_new ();
2277 if (gnome_vfs_get_file_info (uri,
2279 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2281 mime_type = gnome_vfs_file_info_get_mime_type (info);
2282 mime_part = tny_platform_factory_new_mime_part
2283 (modest_runtime_get_platform_factory ());
2284 stream = TNY_STREAM (tny_vfs_stream_new (handle));
2286 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2288 g_object_unref (stream);
2290 content_id = g_strdup_printf ("%d", priv->last_cid);
2291 tny_mime_part_set_content_id (mime_part, content_id);
2292 g_free (content_id);
2295 basename = g_path_get_basename (filename);
2296 tny_mime_part_set_filename (mime_part, basename);
2299 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2300 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2302 info->size == 0, info->size);
2303 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2304 gtk_widget_show_all (priv->attachments_caption);
2305 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2307 g_object_unref (mime_part);
2308 gnome_vfs_file_info_unref (info);
2313 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2316 ModestMsgEditWindowPrivate *priv;
2319 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2320 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2322 if (att_list == NULL) {
2323 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2325 g_object_ref (att_list);
2328 if (tny_list_get_length (att_list) == 0) {
2329 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2331 GtkWidget *confirmation_dialog = NULL;
2332 gboolean dialog_response;
2333 gchar *message = NULL;
2334 gchar *filename = NULL;
2336 if (tny_list_get_length (att_list) == 1) {
2338 iter = tny_list_create_iterator (att_list);
2339 part = (TnyMimePart *) tny_iterator_get_current (iter);
2340 g_object_unref (iter);
2341 if (TNY_IS_MSG (part)) {
2342 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2344 filename = g_strdup (tny_header_get_subject (header));
2345 g_object_unref (header);
2347 if (filename == NULL) {
2348 filename = g_strdup (_("mail_va_no_subject"));
2351 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2353 g_object_unref (part);
2355 filename = g_strdup ("");
2357 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
2358 (tny_list_get_length (att_list) == 1)), filename);
2360 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
2362 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
2363 gtk_widget_destroy (confirmation_dialog);
2364 if (!dialog_response) {
2365 g_object_unref (att_list);
2368 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
2370 for (iter = tny_list_create_iterator (att_list);
2371 !tny_iterator_is_done (iter);
2372 tny_iterator_next (iter)) {
2373 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2374 const gchar *att_id;
2375 tny_list_remove (priv->attachments, (GObject *) mime_part);
2377 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2379 if (tny_list_get_length (priv->attachments) == 0)
2380 gtk_widget_hide (priv->attachments_caption);
2381 att_id = tny_mime_part_get_content_id (mime_part);
2383 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2385 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2386 g_object_unref (mime_part);
2388 g_object_unref (iter);
2391 g_object_unref (att_list);
2393 /* if the last attachment has been removed, focus the Subject: field */
2394 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2395 gtk_widget_grab_focus (priv->subject_field);
2399 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2402 ModestMsgEditWindowPrivate *priv;
2403 GdkColor *new_color;
2404 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2406 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2407 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2410 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2412 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2414 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2416 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2421 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
2424 ModestMsgEditWindowPrivate *priv;
2425 gint new_size_index;
2426 ModestMsgEditWindow *window;
2429 window = MODEST_MSG_EDIT_WINDOW (userdata);
2430 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2431 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2433 if (gtk_check_menu_item_get_active (menu_item)) {
2435 WPTextBufferFormat format;
2437 memset (&format, 0, sizeof (format));
2438 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2440 label = gtk_bin_get_child (GTK_BIN (menu_item));
2442 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
2443 format.cs.font_size = TRUE;
2444 format.cs.text_position = TRUE;
2445 format.cs.font = TRUE;
2446 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
2447 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2449 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2450 GINT_TO_POINTER (wp_get_font_size_index (new_size_index, 12))))
2451 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2453 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2454 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
2455 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2461 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
2464 ModestMsgEditWindowPrivate *priv;
2465 gint new_font_index;
2466 ModestMsgEditWindow *window;
2469 window = MODEST_MSG_EDIT_WINDOW (userdata);
2470 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2471 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2473 if (gtk_check_menu_item_get_active (menu_item)) {
2476 label = gtk_bin_get_child (GTK_BIN (menu_item));
2478 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
2480 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2481 GINT_TO_POINTER(new_font_index)))
2482 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2484 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2485 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2486 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2492 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
2494 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
2495 ModestWindowPrivate *parent_priv;
2496 ModestWindowMgr *mgr;
2497 gboolean is_fullscreen;
2498 GtkAction *fs_toggle_action;
2501 mgr = modest_runtime_get_window_mgr ();
2502 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
2504 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
2506 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2507 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2508 if (is_fullscreen != active)
2509 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2517 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2520 ModestMsgEditWindowPrivate *priv = NULL;
2521 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2523 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2524 if (!priv->update_caption_visibility)
2527 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2529 gtk_widget_show (priv->cc_caption);
2531 gtk_widget_hide (priv->cc_caption);
2533 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2537 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2540 ModestMsgEditWindowPrivate *priv = NULL;
2541 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2543 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2544 if (!priv->update_caption_visibility)
2547 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2549 gtk_widget_show (priv->bcc_caption);
2551 gtk_widget_hide (priv->bcc_caption);
2553 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2557 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2558 ModestRecptEditor *editor)
2560 ModestMsgEditWindowPrivate *priv;
2562 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2563 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2564 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2566 if (editor == NULL) {
2567 GtkWidget *view_focus;
2568 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2570 /* This code should be kept in sync with ModestRecptEditor. The
2571 textview inside the recpt editor is the one that really gets the
2572 focus. As it's inside a scrolled window, and this one inside the
2573 hbox recpt editor inherits from, we'll need to go up in the
2574 hierarchy to know if the text view is part of the recpt editor
2575 or if it's a different text entry */
2577 if (gtk_widget_get_parent (view_focus)) {
2578 GtkWidget *first_parent;
2580 first_parent = gtk_widget_get_parent (view_focus);
2581 if (gtk_widget_get_parent (first_parent) &&
2582 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2583 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2588 editor = MODEST_RECPT_EDITOR (priv->to_field);
2592 modest_address_book_select_addresses (editor);
2597 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2599 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2601 modest_msg_edit_window_open_addressbook (window, NULL);
2605 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2606 gboolean show_toolbar)
2608 ModestWindowPrivate *parent_priv;
2609 const gchar *action_name;
2612 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2613 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2615 /* We can not just use the code of
2616 modest_msg_edit_window_setup_toolbar because it has a
2617 mixture of both initialization and creation code. */
2619 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2621 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2623 /* Update also the actions (to update the toggles in the
2624 menus), we have to do it manually because some other window
2625 of the same time could have changed it (remember that the
2626 toolbar fullscreen mode is shared by all the windows of the
2628 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
2629 action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarFullScreenMenu";
2631 action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarNormalScreenMenu";
2633 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
2634 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
2640 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2641 TnyHeaderFlags priority_flags)
2643 ModestMsgEditWindowPrivate *priv;
2644 ModestWindowPrivate *parent_priv;
2646 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2648 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2649 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2651 if (priv->priority_flags != priority_flags) {
2652 GtkAction *priority_action = NULL;
2654 priv->priority_flags = priority_flags;
2656 switch (priority_flags) {
2657 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2658 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2659 gtk_widget_show (priv->priority_icon);
2660 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2661 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2663 case TNY_HEADER_FLAG_LOW_PRIORITY:
2664 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2665 gtk_widget_show (priv->priority_icon);
2666 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2667 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2670 gtk_widget_hide (priv->priority_icon);
2671 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2672 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2675 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2676 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2681 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2684 ModestMsgEditWindowPrivate *priv;
2685 ModestWindowPrivate *parent_priv;
2686 gint current_format;
2688 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2690 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2691 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2693 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2694 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2696 if (current_format != file_format) {
2697 switch (file_format) {
2698 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2699 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2700 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
2702 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2706 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2707 response = gtk_dialog_run (GTK_DIALOG (dialog));
2708 gtk_widget_destroy (dialog);
2709 if (response == GTK_RESPONSE_OK) {
2710 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2712 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2713 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
2718 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2723 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2726 ModestMsgEditWindowPrivate *priv;
2727 WPTextBufferFormat oldfmt, fmt;
2728 gint old_position = 0;
2732 GdkColor *color = NULL;
2733 gboolean bold, bold_set, italic, italic_set;
2734 gboolean underline, underline_set;
2735 gboolean strikethrough, strikethrough_set;
2736 gboolean position_set;
2737 gboolean font_size_set, font_set, color_set;
2740 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2741 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2743 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2745 /* First we get the currently selected font information */
2746 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2748 switch (oldfmt.text_position) {
2749 case TEXT_POSITION_NORMAL:
2752 case TEXT_POSITION_SUPERSCRIPT:
2760 g_object_set (G_OBJECT (dialog),
2761 "bold", oldfmt.bold != FALSE,
2762 "bold-set", !oldfmt.cs.bold,
2763 "underline", oldfmt.underline != FALSE,
2764 "underline-set", !oldfmt.cs.underline,
2765 "italic", oldfmt.italic != FALSE,
2766 "italic-set", !oldfmt.cs.italic,
2767 "strikethrough", oldfmt.strikethrough != FALSE,
2768 "strikethrough-set", !oldfmt.cs.strikethrough,
2769 "color", &oldfmt.color,
2770 "color-set", !oldfmt.cs.color,
2771 "size", wp_font_size[oldfmt.font_size],
2772 "size-set", !oldfmt.cs.font_size,
2773 "position", old_position,
2774 "position-set", !oldfmt.cs.text_position,
2775 "family", wp_get_font_name (oldfmt.font),
2776 "family-set", !oldfmt.cs.font,
2779 gtk_widget_show_all (dialog);
2780 response = gtk_dialog_run (GTK_DIALOG (dialog));
2781 if (response == GTK_RESPONSE_OK) {
2783 g_object_get( dialog,
2785 "bold-set", &bold_set,
2786 "underline", &underline,
2787 "underline-set", &underline_set,
2789 "italic-set", &italic_set,
2790 "strikethrough", &strikethrough,
2791 "strikethrough-set", &strikethrough_set,
2793 "color-set", &color_set,
2795 "size-set", &font_size_set,
2796 "family", &font_name,
2797 "family-set", &font_set,
2798 "position", &position,
2799 "position-set", &position_set,
2804 if (response == GTK_RESPONSE_OK) {
2805 memset(&fmt, 0, sizeof(fmt));
2811 fmt.italic = italic;
2812 fmt.cs.italic = TRUE;
2814 if (underline_set) {
2815 fmt.underline = underline;
2816 fmt.cs.underline = TRUE;
2818 if (strikethrough_set) {
2819 fmt.strikethrough = strikethrough;
2820 fmt.cs.strikethrough = TRUE;
2825 ? TEXT_POSITION_NORMAL
2826 : ( ( position == 1 )
2827 ? TEXT_POSITION_SUPERSCRIPT
2828 : TEXT_POSITION_SUBSCRIPT );
2829 fmt.cs.text_position = TRUE;
2830 fmt.font_size = oldfmt.font_size;
2834 fmt.cs.color = TRUE;
2837 fmt.font = wp_get_font_index(font_name,
2842 if (font_size_set) {
2843 fmt.cs.font_size = TRUE;
2844 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
2846 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2847 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2849 gtk_widget_destroy (dialog);
2851 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2855 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2857 ModestMsgEditWindowPrivate *priv;
2859 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2860 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2862 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2864 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2865 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2870 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2872 ModestMsgEditWindowPrivate *priv;
2874 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2875 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2877 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2879 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2880 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2885 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2887 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2889 priv->can_undo = can_undo;
2893 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2895 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2897 priv->can_redo = can_redo;
2901 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
2903 ModestMsgEditWindowPrivate *priv;
2904 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2905 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2907 return priv->can_undo;
2911 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
2913 ModestMsgEditWindowPrivate *priv;
2914 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2915 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2917 return priv->can_redo;
2922 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2925 GtkTextIter match_start, match_end;
2927 if (image_id == NULL)
2930 gtk_text_buffer_get_start_iter (buffer, &iter);
2932 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2933 GSList *tags = gtk_text_iter_get_tags (&match_start);
2935 for (node = tags; node != NULL; node = g_slist_next (node)) {
2936 GtkTextTag *tag = (GtkTextTag *) node->data;
2937 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2938 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2939 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2941 offset = gtk_text_iter_get_offset (&match_start);
2942 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2943 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2947 gtk_text_iter_forward_char (&iter);
2952 message_is_empty (ModestMsgEditWindow *window)
2954 ModestMsgEditWindowPrivate *priv = NULL;
2956 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2957 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2959 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
2960 * so we can ignore markup.
2962 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
2965 count = gtk_text_buffer_get_char_count (buf);
2971 msg_body_focus (GtkWidget *focus,
2972 GdkEventFocus *event,
2976 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
2977 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
2978 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
2983 recpt_field_changed (GtkTextBuffer *buffer,
2984 ModestMsgEditWindow *editor)
2986 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
2987 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
2991 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
2993 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
2994 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
2998 modest_msg_edit_window_reset_modified (ModestMsgEditWindow *editor)
3000 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3001 GtkTextBuffer *buffer;
3003 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3004 gtk_text_buffer_set_modified (buffer, FALSE);
3005 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3006 gtk_text_buffer_set_modified (buffer, FALSE);
3007 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3008 gtk_text_buffer_set_modified (buffer, FALSE);
3009 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
3013 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3015 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3016 const char *account_name;
3017 GtkTextBuffer *buffer;
3019 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3020 if (gtk_text_buffer_get_modified (buffer))
3022 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3023 if (gtk_text_buffer_get_modified (buffer))
3025 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3026 if (gtk_text_buffer_get_modified (buffer))
3028 if (gtk_text_buffer_get_modified (priv->text_buffer))
3030 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
3031 if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3042 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3044 ModestMsgEditWindowPrivate *priv = NULL;
3046 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3047 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3049 /* check if there's no recipient added */
3050 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3051 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3052 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3053 /* no recipient contents, then select contacts */
3054 modest_msg_edit_window_open_addressbook (window, NULL);
3058 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3059 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3062 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3063 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3066 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3067 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3071 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3072 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3073 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3080 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3081 ModestMsgEditWindow *window)
3083 modest_msg_edit_window_offer_attach_file (window);
3087 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3089 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3091 return priv->clipboard_text;
3095 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3097 ModestMsgEditWindow *window)
3099 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3100 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3102 if (!GTK_WIDGET_VISIBLE (window))
3105 text = gtk_clipboard_wait_for_text (selection_clipboard);
3107 if (priv->clipboard_text != NULL) {
3108 g_free (priv->clipboard_text);
3110 priv->clipboard_text = text;
3112 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3115 subject_field_move_cursor (GtkEntry *entry,
3116 GtkMovementStep step,
3121 if (!GTK_WIDGET_VISIBLE (window))
3124 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3128 update_window_title (ModestMsgEditWindow *window)
3130 ModestMsgEditWindowPrivate *priv = NULL;
3131 const gchar *subject;
3133 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3134 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3135 if (subject == NULL || subject[0] == '\0')
3136 subject = _("mail_va_new_email");
3138 gtk_window_set_title (GTK_WINDOW (window), subject);
3143 subject_field_changed (GtkEditable *editable,
3144 ModestMsgEditWindow *window)
3146 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3147 update_window_title (window);
3148 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3149 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3150 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3154 subject_field_insert_text (GtkEditable *editable,
3156 gint new_text_length,
3158 ModestMsgEditWindow *window)
3160 GString *result = g_string_new ("");
3162 gint result_len = 0;
3163 const gchar *entry_text = NULL;
3166 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3167 old_length = g_utf8_strlen (entry_text, -1);
3169 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3170 gunichar c = g_utf8_get_char_validated (current, 8);
3171 /* Invalid unichar, stop */
3177 result = g_string_append_unichar (result, c);
3181 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3182 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3185 /* Prevent endless recursion */
3186 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3187 g_signal_emit_by_name (editable, "insert-text",
3188 (gpointer) result->str, (gpointer) result->len,
3189 (gpointer) position, (gpointer) window);
3190 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3194 if (result_len + old_length > 1000) {
3195 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3196 dgettext("hildon-common-strings",
3197 "ckdg_ib_maximum_characters_reached"));
3200 g_string_free (result, TRUE);
3204 text_buffer_insert_text (GtkTextBuffer *buffer,
3207 gint new_text_length,
3208 ModestMsgEditWindow *window)
3210 GString *result = g_string_new ("");
3212 gint result_len = 0;
3213 gboolean changed = FALSE;
3215 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3216 gunichar c = g_utf8_get_char_validated (current, 8);
3217 /* Invalid unichar, stop */
3223 result = g_string_append_c (result, ' ');
3227 result = g_string_append_unichar (result, c);
3233 g_signal_stop_emission_by_name (G_OBJECT (buffer), "insert-text");
3234 g_signal_handlers_block_by_func(G_OBJECT(buffer), G_CALLBACK(text_buffer_insert_text), window);
3235 g_signal_emit_by_name (buffer, "insert-text",
3237 (gpointer) result->str, (gpointer) result->len,
3239 g_signal_handlers_unblock_by_func(G_OBJECT(buffer), G_CALLBACK(text_buffer_insert_text), window);
3242 g_string_free (result, TRUE);
3246 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3249 ModestMsgEditWindowPrivate *priv = NULL;
3251 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3252 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3254 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3257 gtk_widget_show_all (priv->find_toolbar);
3258 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3260 gtk_widget_hide_all (priv->find_toolbar);
3261 gtk_widget_grab_focus (priv->msg_body);
3267 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3269 GtkTextIter *match_start,
3270 GtkTextIter *match_end)
3272 GtkTextIter end_iter;
3273 gchar *str_casefold;
3276 gchar *range_casefold;
3279 gboolean result = FALSE;
3286 gtk_text_iter_forward_to_end (&end_iter);
3288 str_casefold = g_utf8_casefold (str, -1);
3289 str_chars_n = strlen (str);
3291 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3292 range_casefold = g_utf8_casefold (range_text, -1);
3293 range_chars_n = strlen (range_casefold);
3295 if (range_chars_n < str_chars_n) {
3296 g_free (str_casefold);
3297 g_free (range_text);
3298 g_free (range_casefold);
3302 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3303 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3304 if (!g_utf8_collate (range_subtext, str_casefold)) {
3305 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3307 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3308 match_start, match_end, NULL);
3309 g_free (found_text);
3311 g_free (range_subtext);
3315 g_free (str_casefold);
3316 g_free (range_text);
3317 g_free (range_casefold);
3324 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3325 ModestMsgEditWindow *window)
3327 gchar *current_search = NULL;
3328 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3330 GtkTextIter selection_start, selection_end;
3331 GtkTextIter match_start, match_end;
3332 gboolean continue_search = FALSE;
3334 if (message_is_empty (window)) {
3335 g_free (priv->last_search);
3336 priv->last_search = NULL;
3337 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3341 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3342 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3343 g_free (current_search);
3344 g_free (priv->last_search);
3345 priv->last_search = NULL;
3346 /* Information banner about empty search */
3347 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
3351 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3352 continue_search = TRUE;
3354 g_free (priv->last_search);
3355 priv->last_search = g_strdup (current_search);
3358 if (continue_search) {
3359 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3360 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3361 &match_start, &match_end);
3363 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
3365 GtkTextIter buffer_start;
3366 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3367 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3368 &match_start, &match_end);
3370 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
3373 /* Mark as selected the string found in search */
3375 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3376 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3378 g_free (priv->last_search);
3379 priv->last_search = NULL;
3381 g_free (current_search);
3385 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3386 ModestMsgEditWindow *window)
3388 GtkToggleAction *toggle;
3389 ModestWindowPrivate *parent_priv;
3390 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3392 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
3393 gtk_toggle_action_set_active (toggle, FALSE);
3397 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3399 ModestMsgEditWindowPrivate *priv;
3401 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3406 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3409 ModestMsgEditWindowPrivate *priv;
3411 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3417 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3420 ModestMsgEditWindowPrivate *priv;
3421 TnyHeader *header = NULL;
3423 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3424 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3426 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3427 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3429 if (priv->draft_msg != NULL) {
3430 g_object_unref (priv->draft_msg);
3433 if (draft != NULL) {
3434 g_object_ref (draft);
3435 header = tny_msg_get_header (draft);
3436 if (priv->msg_uid) {
3437 g_free (priv->msg_uid);
3438 priv->msg_uid = NULL;
3440 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3441 if (GTK_WIDGET_REALIZED (window))
3442 modest_window_mgr_register_window (mgr, MODEST_WINDOW (window));
3445 priv->draft_msg = draft;
3449 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3450 GtkTextIter *start, GtkTextIter *end,
3453 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3454 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3457 if (tag == NULL+13) return;
3458 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3459 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3460 replace_with_images (window, priv->images);
3465 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3468 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3470 g_return_if_fail (TNY_IS_MIME_PART (part));
3471 tny_list_prepend (priv->attachments, (GObject *) part);
3472 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3473 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3474 gtk_widget_show_all (priv->attachments_caption);
3475 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3479 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3481 ModestMsgEditWindowPrivate *priv;
3483 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3484 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3486 return priv->msg_uid;
3490 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3491 ModestMsgEditWindowWidgetType widget_type)
3493 ModestMsgEditWindowPrivate *priv;
3495 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3496 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3498 switch (widget_type) {
3499 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3500 return priv->msg_body;
3502 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3503 return priv->to_field;
3505 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3506 return priv->cc_field;
3508 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3509 return priv->bcc_field;
3511 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3512 return priv->subject_field;
3514 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3515 return priv->attachments_view;
3523 remove_tags (WPTextBuffer *buffer)
3525 GtkTextIter start, end;
3527 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3528 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3530 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3534 on_account_removed (TnyAccountStore *account_store,
3535 TnyAccount *account,
3538 /* Do nothing if it's a store account, because we use the
3539 transport to send the messages */
3540 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3541 const gchar *parent_acc = NULL;
3542 const gchar *our_acc = NULL;
3544 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3545 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3546 /* Close this window if I'm showing a message of the removed account */
3547 if (strcmp (parent_acc, our_acc) == 0)
3548 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3553 on_zoom_minus_plus_not_implemented (ModestWindow *window)
3555 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3557 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
3563 set_zoom_do_nothing (ModestWindow *window,
3569 get_zoom_do_nothing (ModestWindow *window)