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;
251 GtkWidget *bcc_field;
252 GtkWidget *subject_field;
253 GtkWidget *attachments_view;
254 GtkWidget *priority_icon;
255 GtkWidget *add_attachment_button;
257 GtkWidget *cc_caption;
258 GtkWidget *bcc_caption;
259 gboolean update_caption_visibility;
260 GtkWidget *attachments_caption;
262 GtkTextBuffer *text_buffer;
264 GtkWidget *font_size_toolitem;
265 GtkWidget *font_face_toolitem;
266 GtkWidget *font_color_button;
267 GSList *font_items_group;
268 GtkWidget *font_tool_button_label;
269 GSList *size_items_group;
270 GtkWidget *size_tool_button_label;
272 GtkWidget *find_toolbar;
276 guint scroll_drag_timeout_id;
280 TnyList *attachments;
285 TnyHeaderFlags priority_flags;
287 gboolean can_undo, can_redo;
288 gulong clipboard_change_handler_id;
289 gulong default_clipboard_change_handler_id;
290 gulong account_removed_handler_id;
291 gchar *clipboard_text;
300 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
301 MODEST_TYPE_MSG_EDIT_WINDOW, \
302 ModestMsgEditWindowPrivate))
304 static GtkWindowClass *parent_class = NULL;
306 /* uncomment the following if you have defined any signals */
307 /* static guint signals[LAST_SIGNAL] = {0}; */
310 modest_msg_edit_window_get_type (void)
312 static GType my_type = 0;
314 static const GTypeInfo my_info = {
315 sizeof(ModestMsgEditWindowClass),
316 NULL, /* base init */
317 NULL, /* base finalize */
318 (GClassInitFunc) modest_msg_edit_window_class_init,
319 NULL, /* class finalize */
320 NULL, /* class data */
321 sizeof(ModestMsgEditWindow),
323 (GInstanceInitFunc) modest_msg_edit_window_init,
326 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
327 "ModestMsgEditWindow",
335 save_state (ModestWindow *self)
337 modest_widget_memory_save (modest_runtime_get_conf(),
338 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
343 restore_settings (ModestMsgEditWindow *self)
345 ModestConf *conf = NULL;
347 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
349 conf = modest_runtime_get_conf ();
350 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
351 "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarNormalScreenMenu");
352 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
353 modest_conf_get_bool (conf, MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR, NULL));
354 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
355 "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarFullScreenMenu");
356 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
357 modest_conf_get_bool (conf, MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
359 /* set initial state of cc and bcc */
360 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
361 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
362 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
363 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
364 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
365 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
367 /* Dim at start clipboard actions */
368 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
369 gtk_action_set_sensitive (action, FALSE);
370 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
371 gtk_action_set_sensitive (action, FALSE);
372 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
373 gtk_action_set_sensitive (action, FALSE);
375 modest_widget_memory_restore (conf,
376 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
381 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
383 GObjectClass *gobject_class;
384 ModestWindowClass *modest_window_class;
385 gobject_class = (GObjectClass*) klass;
386 modest_window_class = (ModestWindowClass*) klass;
388 parent_class = g_type_class_peek_parent (klass);
389 gobject_class->finalize = modest_msg_edit_window_finalize;
391 modest_window_class->set_zoom_func = set_zoom_do_nothing;
392 modest_window_class->get_zoom_func = get_zoom_do_nothing;
393 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
394 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
395 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
396 modest_window_class->save_state_func = save_state;
397 modest_window_class->disconnect_signals_func = modest_msg_edit_window_disconnect_signals;
399 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
403 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
405 ModestMsgEditWindowPrivate *priv;
406 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
408 priv->msg_body = NULL;
410 priv->from_field = NULL;
411 priv->to_field = NULL;
412 priv->cc_field = NULL;
413 priv->bcc_field = NULL;
414 priv->subject_field = NULL;
415 priv->attachments = TNY_LIST (tny_simple_list_new ());
416 priv->images = TNY_LIST (tny_simple_list_new ());
417 priv->images_size = 0;
418 priv->images_count = 0;
421 priv->cc_caption = NULL;
422 priv->bcc_caption = NULL;
423 priv->update_caption_visibility = FALSE;
425 priv->priority_flags = 0;
427 priv->find_toolbar = NULL;
428 priv->last_search = NULL;
430 priv->draft_msg = NULL;
431 priv->outbox_msg = NULL;
432 priv->msg_uid = NULL;
434 priv->can_undo = FALSE;
435 priv->can_redo = FALSE;
436 priv->clipboard_change_handler_id = 0;
437 priv->default_clipboard_change_handler_id = 0;
438 priv->account_removed_handler_id = 0;
439 priv->clipboard_text = NULL;
442 priv->scroll_drag_timeout_id = 0;
443 priv->last_upper = 0.0;
445 modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
446 GTK_WINDOW(obj),"applications_email_editor");
448 if (!is_wp_text_buffer_started) {
449 is_wp_text_buffer_started = TRUE;
450 wp_text_buffer_library_init ();
455 hildon_program_add_window (hildon_program_get_instance(),
460 /* FIXME: this is a dup from the one in gtk/ */
463 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
465 static ModestPairList*
466 get_transports (void)
468 GSList *transports = NULL;
470 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
471 GSList *accounts = modest_account_mgr_account_names (account_mgr,
472 TRUE /* only enabled accounts. */);
474 GSList *cursor = accounts;
476 gchar *account_name = cursor->data;
477 gchar *from_string = NULL;
479 from_string = modest_account_mgr_get_from_string (account_mgr,
483 if (from_string && account_name) {
484 gchar *name = account_name;
485 ModestPair *pair = modest_pair_new ((gpointer) name,
486 (gpointer) from_string , TRUE);
487 transports = g_slist_prepend (transports, pair);
490 cursor = cursor->next;
492 g_slist_free (accounts); /* only free the accounts, not the elements,
493 * because they are used in the pairlist */
498 * Search an (account, address) ModestPairList for a pair whose
499 * address matches the one in the From: header of a TnyMsg
501 * @result: A ModestPair * with a matching address, or NULL if none found
504 find_transport_from_message_sender (ModestPairList *transports, TnyMsg *msg)
506 g_return_val_if_fail (transports, NULL);
507 g_return_val_if_fail (msg, NULL);
509 ModestPair *account_pair = NULL;
510 TnyHeader *header = tny_msg_get_header (msg);
512 if (header != NULL && tny_header_get_from (header)) {
513 char *from_addr = modest_text_utils_get_email_address (tny_header_get_from (header));
515 for (iter = transports; iter && !account_pair; iter = iter->next) {
516 ModestPair *pair = (ModestPair *) iter->data;
517 char *account_addr = modest_text_utils_get_email_address ((char *) pair->second);
518 if (account_addr && !strcasecmp(from_addr, account_addr)) {
521 g_free (account_addr);
527 g_object_unref (header);
532 static void window_focus (GtkWindow *window,
536 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
540 scroll_drag_timeout (gpointer userdata)
542 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
543 ModestMsgEditWindowPrivate *priv;
545 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
547 correct_scroll_without_drag_check (win);
549 priv->scroll_drag_timeout_id = 0;
555 correct_scroll_without_drag_check (ModestMsgEditWindow *w)
557 ModestMsgEditWindowPrivate *priv;
560 GdkRectangle rectangle;
566 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
568 if (!gtk_widget_is_focus (priv->msg_body))
571 insert = gtk_text_buffer_get_insert (priv->text_buffer);
572 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
574 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
575 vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll));
576 offset = priv->msg_body->allocation.y;
578 new_value = vadj->value;
580 if ((offset + rectangle.y + rectangle.height) >
581 ((gint) (vadj->value +vadj->page_size))) {
582 new_value = (offset + rectangle.y) + vadj->page_size * 0.75;
583 if (new_value > vadj->upper - vadj->page_size)
584 new_value = vadj->upper - vadj->page_size;
585 } else if ((offset + rectangle.y) < ((gint) vadj->value)) {
586 new_value = (offset + rectangle.y - vadj->page_size * 0.75);
587 if (((gint) (new_value + vadj->page_size)) < (offset + rectangle.y + rectangle.height))
588 new_value = offset + rectangle.y + rectangle.height - (gint) vadj->page_size;
591 if (new_value > vadj->value)
592 new_value = vadj->value;
595 if (vadj->value != new_value) {
596 g_signal_emit_by_name (GTK_TEXT_VIEW(priv->msg_body)->layout,
598 vadj->value = new_value;
599 gtk_adjustment_value_changed (vadj);
600 /* invalidate body */
601 window = gtk_widget_get_parent_window (priv->msg_body);
603 gdk_window_invalidate_rect (window, NULL, TRUE);
609 correct_scroll (ModestMsgEditWindow *w)
611 ModestMsgEditWindowPrivate *priv;
613 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
614 if (gtk_grab_get_current () == priv->msg_body) {
615 if (priv->scroll_drag_timeout_id == 0) {
616 priv->scroll_drag_timeout_id = g_timeout_add (500, (GSourceFunc) scroll_drag_timeout,
622 correct_scroll_without_drag_check (w);
626 text_buffer_end_user_action (GtkTextBuffer *buffer,
627 ModestMsgEditWindow *userdata)
630 correct_scroll (userdata);
634 text_buffer_mark_set (GtkTextBuffer *buffer,
637 ModestMsgEditWindow *userdata)
639 gtk_text_buffer_begin_user_action (buffer);
640 gtk_text_buffer_end_user_action (buffer);
643 void vadj_changed (GtkAdjustment *adj,
644 ModestMsgEditWindow *window)
646 ModestMsgEditWindowPrivate *priv;
648 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
650 if (priv->last_upper != adj->upper) {
651 priv->last_upper = adj->upper;
652 correct_scroll (window);
657 connect_signals (ModestMsgEditWindow *obj)
659 ModestMsgEditWindowPrivate *priv;
661 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
663 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
664 G_CALLBACK (text_buffer_refresh_attributes), obj);
665 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
666 G_CALLBACK (text_buffer_can_undo), obj);
667 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
668 G_CALLBACK (text_buffer_can_redo), obj);
669 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
670 G_CALLBACK (body_changed), obj);
671 g_signal_connect (G_OBJECT (priv->text_buffer), "insert-text",
672 G_CALLBACK (text_buffer_insert_text), obj);
673 g_signal_connect (G_OBJECT (obj), "window-state-event",
674 G_CALLBACK (modest_msg_edit_window_window_state_event),
676 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
677 G_CALLBACK (text_buffer_end_user_action), obj);
678 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
679 G_CALLBACK (text_buffer_mark_set), obj);
680 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
681 G_CALLBACK (text_buffer_apply_tag), obj);
682 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
683 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
684 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
685 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
686 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
687 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
689 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
690 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
692 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
693 G_CALLBACK (msg_body_focus), obj);
694 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
695 G_CALLBACK (msg_body_focus), obj);
696 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
697 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
698 "changed", G_CALLBACK (recpt_field_changed), obj);
699 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
700 "changed", G_CALLBACK (recpt_field_changed), obj);
701 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
702 "changed", G_CALLBACK (recpt_field_changed), obj);
703 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
704 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
705 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
707 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
708 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
710 g_signal_connect (G_OBJECT (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll))),
712 G_CALLBACK (vadj_changed),
715 priv->clipboard_change_handler_id =
716 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
717 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
718 priv->default_clipboard_change_handler_id =
719 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
720 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
725 init_window (ModestMsgEditWindow *obj)
727 GtkWidget *from_caption, *to_caption, *subject_caption;
728 GtkWidget *main_vbox;
729 ModestMsgEditWindowPrivate *priv;
730 GtkActionGroup *action_group;
731 ModestWindowPrivate *parent_priv;
732 GdkPixbuf *window_icon = NULL;
733 GError *error = NULL;
735 GtkSizeGroup *size_group;
736 GtkWidget *subject_box;
737 GtkWidget *attachment_icon;
738 GtkWidget *window_box;
739 #if (GTK_MINOR_VERSION >= 10)
740 GdkAtom deserialize_type;
742 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
743 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
745 parent_priv->ui_manager = gtk_ui_manager_new();
746 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
747 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
749 /* Add common actions */
750 gtk_action_group_add_actions (action_group,
751 modest_msg_edit_action_entries,
752 G_N_ELEMENTS (modest_msg_edit_action_entries),
754 gtk_action_group_add_toggle_actions (action_group,
755 modest_msg_edit_toggle_action_entries,
756 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
758 gtk_action_group_add_radio_actions (action_group,
759 modest_msg_edit_alignment_radio_action_entries,
760 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
762 G_CALLBACK (modest_ui_actions_on_change_justify),
764 gtk_action_group_add_radio_actions (action_group,
765 modest_msg_edit_priority_action_entries,
766 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
768 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
770 gtk_action_group_add_radio_actions (action_group,
771 modest_msg_edit_file_format_action_entries,
772 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
773 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
774 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
776 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
777 g_object_unref (action_group);
779 /* Load the UI definition */
780 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
783 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
784 g_clear_error (&error);
787 /* Add accelerators */
788 gtk_window_add_accel_group (GTK_WINDOW (obj),
789 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
791 parent_priv->menubar = NULL;
793 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
795 /* Note: This ModestPairList* must exist for as long as the combo
796 * that uses it, because the ModestComboBox uses the ID opaquely,
797 * so it can't know how to manage its memory. */
798 priv->from_field = modest_combo_box_new (NULL, g_str_equal);
800 priv->to_field = modest_recpt_editor_new ();
801 priv->cc_field = modest_recpt_editor_new ();
802 priv->bcc_field = modest_recpt_editor_new ();
803 subject_box = gtk_hbox_new (FALSE, 0);
804 priv->priority_icon = gtk_image_new ();
805 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
806 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
807 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
808 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
809 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
810 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
811 priv->add_attachment_button = gtk_button_new ();
812 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
813 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
814 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
815 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
816 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
817 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
818 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
819 priv->attachments_view = modest_attachments_view_new (NULL);
821 priv->header_box = gtk_vbox_new (FALSE, 0);
823 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
824 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
825 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
826 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
827 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
828 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
829 g_object_unref (size_group);
831 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
832 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
833 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
834 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
835 gtk_size_group_add_widget (size_group, priv->subject_field);
836 gtk_size_group_add_widget (size_group, priv->attachments_view);
837 g_object_unref (size_group);
839 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
840 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
841 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
842 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
843 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
844 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
845 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
848 priv->msg_body = wp_text_view_new ();
849 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
850 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
851 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
852 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
853 #if (GTK_MINOR_VERSION >= 10)
854 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
855 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
857 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
858 deserialize_type, TRUE);
860 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
862 priv->find_toolbar = hildon_find_toolbar_new (NULL);
863 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
865 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
867 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
868 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
869 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
870 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->scroll), TRUE);
872 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
874 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
875 priv->frame = gtk_frame_new (NULL);
876 gtk_box_pack_start (GTK_BOX(main_vbox), priv->frame, TRUE, TRUE, 0);
878 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
879 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
880 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
882 window_box = gtk_vbox_new (FALSE, 0);
883 gtk_container_add (GTK_CONTAINER(obj), window_box);
885 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
887 gtk_container_add (GTK_CONTAINER (priv->frame), priv->msg_body);
889 /* Set window icon */
890 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
892 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
893 g_object_unref (window_icon);
898 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
900 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
902 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
903 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
904 priv->clipboard_change_handler_id))
905 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
906 priv->clipboard_change_handler_id);
907 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
908 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
909 priv->default_clipboard_change_handler_id))
910 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
911 priv->default_clipboard_change_handler_id);
913 if (priv->account_removed_handler_id &&
914 g_signal_handler_is_connected (modest_runtime_get_account_store (),
915 priv->account_removed_handler_id))
916 g_signal_handler_disconnect(modest_runtime_get_account_store (),
917 priv->account_removed_handler_id);
921 modest_msg_edit_window_finalize (GObject *obj)
923 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
925 /* Sanity check: shouldn't be needed, the window mgr should
926 call this function before */
927 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
929 if (priv->clipboard_text != NULL) {
930 g_free (priv->clipboard_text);
931 priv->clipboard_text = NULL;
934 if (priv->draft_msg != NULL) {
935 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
936 if (TNY_IS_HEADER (header)) {
937 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
938 modest_window_mgr_unregister_header (mgr, header);
940 g_object_unref (priv->draft_msg);
941 priv->draft_msg = NULL;
943 if (priv->outbox_msg != NULL) {
944 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
945 if (TNY_IS_HEADER (header)) {
946 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
947 modest_window_mgr_unregister_header (mgr, header);
949 g_object_unref (priv->outbox_msg);
950 priv->outbox_msg = NULL;
952 if (priv->scroll_drag_timeout_id > 0) {
953 g_source_remove (priv->scroll_drag_timeout_id);
954 priv->scroll_drag_timeout_id = 0;
956 g_free (priv->msg_uid);
957 g_free (priv->last_search);
958 g_slist_free (priv->font_items_group);
959 g_slist_free (priv->size_items_group);
960 g_object_unref (priv->attachments);
961 g_object_unref (priv->images);
963 /* This had to stay alive for as long as the combobox that used it: */
964 modest_pair_list_free (priv->from_field_protos);
966 G_OBJECT_CLASS(parent_class)->finalize (obj);
970 pixbuf_from_stream (TnyStream *stream, const gchar *mime_type, guint64 *stream_size)
972 GdkPixbufLoader *loader;
978 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
980 if (loader == NULL) {
986 tny_stream_reset (TNY_STREAM (stream));
987 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
988 unsigned char read_buffer[128];
990 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
992 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
996 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
997 g_object_ref (pixbuf);
998 gdk_pixbuf_loader_close (loader, NULL);
999 g_object_unref (loader);
1001 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1002 GdkPixbuf *new_pixbuf;
1004 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1005 gdk_pixbuf_get_width (pixbuf);
1006 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1007 g_object_unref (pixbuf);
1008 pixbuf = new_pixbuf;
1012 *stream_size = size;
1018 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1020 ModestMsgEditWindowPrivate *priv;
1023 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1025 for (iter = tny_list_create_iterator (attachments);
1026 !tny_iterator_is_done (iter);
1027 tny_iterator_next (iter)) {
1028 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1029 const gchar *cid = tny_mime_part_get_content_id (part);
1030 const gchar *mime_type = tny_mime_part_get_content_type (part);
1031 if ((cid != NULL)&&(mime_type != NULL)) {
1032 guint64 stream_size;
1033 TnyStream *stream = tny_mime_part_get_stream (part);
1034 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
1037 g_object_unref (stream);
1039 if (pixbuf != NULL) {
1040 priv->images_count ++;
1041 priv->images_size += stream_size;
1042 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1043 g_object_unref (pixbuf);
1046 g_object_unref (part);
1048 g_object_unref (iter);
1052 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1054 TnyMimePart *parent = NULL;
1055 const gchar *content_type = NULL;
1056 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1058 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1060 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1061 parent = g_object_ref (msg);
1062 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1063 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1066 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1067 iter = tny_list_create_iterator (parts);
1068 while (!tny_iterator_is_done (iter)) {
1070 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1071 content_type = tny_mime_part_get_content_type (part);
1072 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1076 g_object_unref (part);
1078 tny_iterator_next (iter);
1080 g_object_unref (iter);
1081 g_object_unref (parts);
1084 if (parent != NULL) {
1085 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1088 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1089 iter = tny_list_create_iterator (parts);
1090 while (!tny_iterator_is_done (iter)) {
1092 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1093 content_type = tny_mime_part_get_content_type (part);
1094 if (content_type && g_str_has_prefix (content_type, "image/")) {
1095 tny_list_prepend (priv->images, (GObject *) part);
1097 g_object_unref (part);
1098 tny_iterator_next (iter);
1100 g_object_unref (iter);
1101 g_object_unref (parts);
1102 g_object_unref (parent);
1107 update_last_cid (ModestMsgEditWindow *self, TnyList *attachments)
1110 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1112 for (iter = tny_list_create_iterator (attachments) ;
1113 !tny_iterator_is_done (iter);
1114 tny_iterator_next (iter)) {
1115 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1116 const gchar *cid = tny_mime_part_get_content_id (part);
1118 char *invalid = NULL;
1119 gint int_cid = strtol (cid, &invalid, 10);
1120 if ((invalid != NULL) && (*invalid == '\0') && (int_cid > priv->last_cid)) {
1121 priv->last_cid = int_cid;
1124 g_object_unref (part);
1126 g_object_unref (iter);
1130 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1133 const gchar *to, *cc, *bcc, *subject;
1135 ModestMsgEditWindowPrivate *priv;
1137 TnyHeaderFlags priority_flags;
1138 TnyFolder *msg_folder;
1139 gboolean is_html = FALSE;
1141 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1142 g_return_if_fail (TNY_IS_MSG (msg));
1144 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1146 header = tny_msg_get_header (msg);
1147 to = tny_header_get_to (header);
1148 cc = tny_header_get_cc (header);
1149 bcc = tny_header_get_bcc (header);
1150 subject = tny_header_get_subject (header);
1151 priority_flags = tny_header_get_priority (header);
1154 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1156 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1157 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1158 gtk_widget_show (priv->cc_caption);
1159 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1160 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1161 gtk_widget_hide (priv->cc_caption);
1164 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1165 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1166 gtk_widget_show (priv->bcc_caption);
1167 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1168 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1169 gtk_widget_hide (priv->bcc_caption);
1172 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1173 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1176 update_window_title (self);
1178 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1179 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1181 if ((body == NULL)||(body[0] == '\0')) {
1183 body = modest_text_utils_convert_to_html ("");
1186 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1187 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1190 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1193 /* Add attachments to the view */
1194 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1195 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1196 if (tny_list_get_length (priv->attachments) == 0) {
1197 gtk_widget_hide (priv->attachments_caption);
1199 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1200 gtk_widget_show_all (priv->attachments_caption);
1202 get_related_images (self, msg);
1203 update_last_cid (self, priv->attachments);
1204 update_last_cid (self, priv->images);
1205 replace_with_images (self, priv->images);
1207 if (preserve_is_rich && !is_html) {
1208 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1209 /* Get the default format required from configuration */
1210 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1211 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1214 /* Set the default focus depending on having already a To: field or not */
1215 if ((!to)||(*to == '\0')) {
1216 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1218 gtk_widget_grab_focus (priv->msg_body);
1221 /* TODO: lower priority, select in the From: combo to the
1222 value that comes from msg <- not sure, should it be
1225 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1227 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1228 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1230 modest_msg_edit_window_reset_modified (self);
1232 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1233 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1234 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1235 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1237 if (priv->msg_uid) {
1238 g_free (priv->msg_uid);
1239 priv->msg_uid = NULL;
1242 /* we should set a reference to the incoming message if it is a draft */
1243 msg_folder = tny_msg_get_folder (msg);
1245 if (modest_tny_folder_is_local_folder (msg_folder)) {
1246 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1247 if (type == TNY_FOLDER_TYPE_INVALID)
1248 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1250 if (type == TNY_FOLDER_TYPE_DRAFTS)
1251 priv->draft_msg = g_object_ref(msg);
1252 if (type == TNY_FOLDER_TYPE_OUTBOX)
1253 priv->outbox_msg = g_object_ref(msg);
1254 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1256 g_object_unref (msg_folder);
1261 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
1264 GList *item_children, *node;
1265 GtkWidget *bin_child;
1267 bin_child = gtk_bin_get_child (GTK_BIN(item));
1269 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
1271 for (node = item_children; node != NULL; node = g_list_next (node)) {
1272 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
1273 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
1276 g_list_free (item_children);
1280 menu_tool_button_dont_expand (GtkMenuToolButton *item)
1283 GList *item_children, *node;
1285 box = gtk_bin_get_child (GTK_BIN (item));
1286 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
1287 item_children = gtk_container_get_children (GTK_CONTAINER (box));
1289 for (node = item_children; node != NULL; node = g_list_next (node)) {
1290 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
1291 if (GTK_IS_TOGGLE_BUTTON (node->data))
1292 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
1293 else if (GTK_IS_BUTTON (node->data))
1294 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
1296 g_list_free (item_children);
1301 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1303 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1304 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1305 GtkWidget *placeholder;
1306 GtkWidget *tool_item;
1311 GtkWidget *sizes_menu;
1312 GtkWidget *fonts_menu;
1313 GSList *radio_group = NULL;
1314 GSList *node = NULL;
1318 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1319 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1321 /* Font color placeholder */
1322 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1323 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1326 tool_item = GTK_WIDGET (gtk_tool_item_new ());
1327 priv->font_color_button = hildon_color_button_new ();
1328 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
1329 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1330 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
1331 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1332 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1333 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1334 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1336 G_CALLBACK (modest_msg_edit_window_color_button_change),
1339 /* Font size and face placeholder */
1340 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1341 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1343 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1344 priv->size_tool_button_label = gtk_label_new (NULL);
1345 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1346 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1347 size_text,"</span>", NULL);
1348 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1350 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
1351 sizes_menu = gtk_menu_new ();
1352 priv->size_items_group = NULL;
1354 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1355 GtkWidget *size_menu_item;
1357 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1358 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
1359 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
1360 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
1361 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
1362 gtk_widget_show (size_menu_item);
1364 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
1368 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1369 GtkWidget *item = (GtkWidget *) node->data;
1370 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
1374 priv->size_items_group = g_slist_reverse (priv->size_items_group);
1375 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
1376 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1377 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1378 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1379 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1380 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1381 priv->font_size_toolitem = tool_item;
1384 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1385 priv->font_tool_button_label = gtk_label_new (NULL);
1386 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1387 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1389 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
1390 fonts_menu = gtk_menu_new ();
1391 priv->font_items_group = NULL;
1393 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1394 GtkWidget *font_menu_item;
1395 GtkWidget *child_label;
1397 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
1398 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
1399 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
1400 wp_get_font_name (font_index), "</span>", NULL);
1401 gtk_label_set_markup (GTK_LABEL (child_label), markup);
1404 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
1405 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
1406 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
1407 gtk_widget_show (font_menu_item);
1409 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
1412 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1413 GtkWidget *item = (GtkWidget *) node->data;
1414 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
1417 priv->font_items_group = g_slist_reverse (priv->font_items_group);
1418 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
1419 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1420 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1421 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1422 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1423 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1424 priv->font_face_toolitem = tool_item;
1426 /* Set expand and homogeneous for remaining items */
1427 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1428 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1429 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1430 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1431 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1432 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1433 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1434 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1435 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1437 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1438 will not show the tool items added to the placeholders) */
1439 gtk_widget_show_all (parent_priv->toolbar);
1441 /* Set the no show all *after* showing all items. We do not
1442 want the toolbar to be shown with a show all because it
1443 could go agains the gconf setting regarding showing or not
1444 the toolbar of the editor window */
1445 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1451 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean preserve_is_rich)
1454 ModestWindowPrivate *parent_priv;
1455 ModestMsgEditWindowPrivate *priv;
1456 ModestPair *account_pair = NULL;
1457 ModestDimmingRulesGroup *menu_rules_group = NULL;
1458 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1459 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1460 ModestWindowMgr *mgr = NULL;
1462 g_return_val_if_fail (msg, NULL);
1463 g_return_val_if_fail (account_name, NULL);
1465 mgr = modest_runtime_get_window_mgr ();
1467 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1469 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1470 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1472 /* Menubar. Update the state of some toggles */
1473 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1474 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
1475 priv->from_field_protos = get_transports ();
1476 modest_combo_box_set_pair_list (MODEST_COMBO_BOX (priv->from_field), priv->from_field_protos);
1477 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1478 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1481 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1483 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1485 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1487 account_pair = find_transport_from_message_sender (priv->from_field_protos, msg);
1488 if (account_pair == NULL) {
1489 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
1491 if (account_pair != NULL)
1492 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
1494 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new ();
1495 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1496 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1497 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1498 /* Add common dimming rules */
1499 modest_dimming_rules_group_add_rules (menu_rules_group,
1500 modest_msg_edit_window_menu_dimming_entries,
1501 G_N_ELEMENTS (modest_msg_edit_window_menu_dimming_entries),
1502 MODEST_WINDOW (obj));
1503 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1504 modest_msg_edit_window_toolbar_dimming_entries,
1505 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1506 MODEST_WINDOW (obj));
1507 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_button,
1508 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1509 MODEST_WINDOW (obj));
1510 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1511 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1512 MODEST_WINDOW (obj));
1513 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1514 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1515 MODEST_WINDOW (obj));
1516 modest_dimming_rules_group_add_rules (clipboard_rules_group,
1517 modest_msg_edit_window_clipboard_dimming_entries,
1518 G_N_ELEMENTS (modest_msg_edit_window_clipboard_dimming_entries),
1519 MODEST_WINDOW (obj));
1520 /* Insert dimming rules group for this window */
1521 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1522 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1523 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1524 /* Checks the dimming rules */
1525 g_object_unref (menu_rules_group);
1526 g_object_unref (toolbar_rules_group);
1527 g_object_unref (clipboard_rules_group);
1528 gtk_widget_show_all (GTK_WIDGET (obj));
1529 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, MODEST_MSG_EDIT_WINDOW (obj));
1531 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1533 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1535 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1536 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1537 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1538 priv->update_caption_visibility = TRUE;
1540 modest_msg_edit_window_reset_modified (MODEST_MSG_EDIT_WINDOW (obj));
1542 /* Track account-removed signal, this window should be closed
1543 in the case we're creating a mail associated to the account
1545 priv->account_removed_handler_id =
1546 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1548 G_CALLBACK(on_account_removed),
1551 return (ModestWindow*) obj;
1555 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1557 GString **string_buffer = (GString **) user_data;
1559 *string_buffer = g_string_append (*string_buffer, buffer);
1565 * @result: A new string which should be freed with g_free().
1568 get_formatted_data (ModestMsgEditWindow *edit_window)
1570 ModestMsgEditWindowPrivate *priv;
1571 GString *string_buffer = g_string_new ("");
1573 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1575 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1577 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1579 return g_string_free (string_buffer, FALSE);
1584 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1587 const gchar *account_name;
1588 ModestMsgEditWindowPrivate *priv;
1589 TnyIterator *att_iter;
1591 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1593 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1595 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1596 g_return_val_if_fail (account_name, NULL);
1599 /* don't free these (except from) */
1600 data = g_slice_new0 (MsgData);
1601 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1603 data->account_name = g_strdup (account_name);
1604 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1605 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1606 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1607 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1608 if (priv->draft_msg) {
1609 data->draft_msg = g_object_ref (priv->draft_msg);
1610 } else if (priv->outbox_msg) {
1611 data->draft_msg = g_object_ref (priv->outbox_msg);
1613 data->draft_msg = NULL;
1616 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1618 gtk_text_buffer_get_bounds (buf, &b, &e);
1619 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1621 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1622 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1624 data->html_body = NULL;
1626 /* deep-copy the data */
1627 att_iter = tny_list_create_iterator (priv->attachments);
1628 data->attachments = NULL;
1629 while (!tny_iterator_is_done (att_iter)) {
1630 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1631 if (!(TNY_IS_MIME_PART(part))) {
1632 g_warning ("strange data in attachment list");
1633 g_object_unref (part);
1634 tny_iterator_next (att_iter);
1637 data->attachments = g_list_append (data->attachments,
1639 tny_iterator_next (att_iter);
1641 g_object_unref (att_iter);
1643 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1644 att_iter = tny_list_create_iterator (priv->images);
1645 data->images = NULL;
1646 while (!tny_iterator_is_done (att_iter)) {
1647 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1649 if (!(TNY_IS_MIME_PART(part))) {
1650 g_warning ("strange data in attachment list");
1651 g_object_unref (part);
1652 tny_iterator_next (att_iter);
1655 cid = tny_mime_part_get_content_id (part);
1657 gchar *image_tag_id;
1658 GtkTextTag *image_tag;
1660 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1661 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1662 g_free (image_tag_id);
1664 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1666 ((gtk_text_iter_has_tag (&iter, image_tag))||
1667 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1668 data->images = g_list_append (data->images,
1669 g_object_ref (part));
1671 g_object_unref (part);
1672 tny_iterator_next (att_iter);
1674 g_object_unref (att_iter);
1676 data->priority_flags = priv->priority_flags;
1683 unref_gobject (GObject *obj, gpointer data)
1685 if (!G_IS_OBJECT(obj))
1687 g_object_unref (obj);
1691 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1694 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1702 g_free (data->from);
1703 g_free (data->subject);
1704 g_free (data->plain_body);
1705 g_free (data->html_body);
1706 g_free (data->account_name);
1708 if (data->draft_msg != NULL) {
1709 g_object_unref (data->draft_msg);
1710 data->draft_msg = NULL;
1713 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1714 g_list_free (data->attachments);
1715 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1716 g_list_free (data->images);
1718 g_slice_free (MsgData, data);
1722 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1724 guint64 *parts_size)
1726 ModestMsgEditWindowPrivate *priv;
1728 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1730 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1732 /* TODO: add images */
1733 *parts_size += priv->images_size;
1734 *parts_count += priv->images_count;
1739 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1742 ModestMsgEditWindowPrivate *priv = NULL;
1743 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1745 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1747 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1749 return MODEST_MSG_EDIT_FORMAT_HTML;
1751 return MODEST_MSG_EDIT_FORMAT_TEXT;
1755 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1756 ModestMsgEditFormat format)
1758 ModestMsgEditWindowPrivate *priv;
1760 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1761 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1764 case MODEST_MSG_EDIT_FORMAT_HTML:
1765 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1767 case MODEST_MSG_EDIT_FORMAT_TEXT:
1768 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1771 g_return_if_reached ();
1775 ModestMsgEditFormatState *
1776 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1778 ModestMsgEditFormatState *format_state = NULL;
1779 ModestMsgEditWindowPrivate *priv;
1780 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1782 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1783 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1785 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1787 format_state = g_new0 (ModestMsgEditFormatState, 1);
1788 format_state->bold = buffer_format->bold&0x1;
1789 format_state->italics = buffer_format->italic&0x1;
1790 format_state->bullet = buffer_format->bullet&0x1;
1791 format_state->color = buffer_format->color;
1792 format_state->font_size = buffer_format->font_size;
1793 format_state->font_family = wp_get_font_name (buffer_format->font);
1794 format_state->justification = buffer_format->justification;
1795 g_free (buffer_format);
1797 return format_state;
1802 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1803 const ModestMsgEditFormatState *format_state)
1805 ModestMsgEditWindowPrivate *priv;
1806 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1807 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1808 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1809 g_return_if_fail (format_state != NULL);
1811 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1812 gtk_widget_grab_focus (priv->msg_body);
1813 buffer_format->bold = (format_state->bold != FALSE);
1814 buffer_format->italic = (format_state->italics != FALSE);
1815 buffer_format->color = format_state->color;
1816 buffer_format->font_size = format_state->font_size;
1817 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1818 buffer_format->justification = format_state->justification;
1819 buffer_format->bullet = format_state->bullet;
1821 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1823 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1824 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1825 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1826 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1827 buffer_format->cs.font = (buffer_format->font != current_format->font);
1828 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1829 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1831 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1832 if (buffer_format->cs.bold) {
1833 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1834 GINT_TO_POINTER (buffer_format->bold&0x1));
1836 if (buffer_format->cs.italic) {
1837 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1838 GINT_TO_POINTER (buffer_format->italic&0x1));
1840 if (buffer_format->cs.color) {
1841 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1842 GINT_TO_POINTER (&(buffer_format->color)));
1844 if (buffer_format->cs.font_size) {
1845 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1846 GINT_TO_POINTER (buffer_format->font_size));
1848 if (buffer_format->cs.justification) {
1849 switch (buffer_format->justification) {
1850 case GTK_JUSTIFY_LEFT:
1851 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1852 GINT_TO_POINTER(TRUE));
1854 case GTK_JUSTIFY_CENTER:
1855 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1856 GINT_TO_POINTER(TRUE));
1858 case GTK_JUSTIFY_RIGHT:
1859 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1860 GINT_TO_POINTER(TRUE));
1867 if (buffer_format->cs.font) {
1868 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1869 GINT_TO_POINTER (buffer_format->font));
1871 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1872 if (buffer_format->cs.bullet) {
1873 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
1874 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
1876 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1878 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
1880 g_free (current_format);
1885 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1887 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1889 ModestWindowPrivate *parent_priv;
1890 ModestMsgEditWindowPrivate *priv;
1891 GtkWidget *new_size_menuitem;
1892 GtkWidget *new_font_menuitem;
1894 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1895 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1897 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1898 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1899 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1900 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1902 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1903 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1904 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1907 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1909 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1910 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1912 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1913 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1915 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
1916 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
1919 switch (buffer_format->justification)
1921 case GTK_JUSTIFY_LEFT:
1922 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentLeftMenu");
1924 case GTK_JUSTIFY_CENTER:
1925 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentCenterMenu");
1927 case GTK_JUSTIFY_RIGHT:
1928 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentRightMenu");
1935 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1937 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1938 G_CALLBACK (modest_msg_edit_window_color_button_change),
1940 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1941 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1942 G_CALLBACK (modest_msg_edit_window_color_button_change),
1945 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1946 buffer_format->font_size))->data);
1947 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1951 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1952 markup = g_strconcat ("<span font_family='Sans'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1953 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1955 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1956 G_CALLBACK (modest_msg_edit_window_size_change),
1958 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1959 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1960 G_CALLBACK (modest_msg_edit_window_size_change),
1964 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1965 buffer_format->font))->data);
1966 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1970 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1971 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1972 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1974 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1975 G_CALLBACK (modest_msg_edit_window_font_change),
1977 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1978 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1979 G_CALLBACK (modest_msg_edit_window_font_change),
1983 g_free (buffer_format);
1987 #ifdef MODEST_HILDON_VERSION_0
1989 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1992 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1993 ModestMsgEditWindowPrivate *priv;
1994 GtkWidget *dialog = NULL;
1996 GdkColor *new_color = NULL;
1998 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1999 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2001 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2002 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2003 g_free (buffer_format);
2005 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2006 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2007 if (new_color != NULL) {
2008 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2009 (gpointer) new_color);
2012 gtk_widget_destroy (dialog);
2017 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2020 ModestMsgEditWindowPrivate *priv;
2021 GtkWidget *dialog = NULL;
2023 GdkColor *old_color = NULL;
2024 const GdkColor *new_color = NULL;
2026 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2027 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2029 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2030 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2032 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2033 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2034 if (new_color != NULL)
2035 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2037 gtk_widget_destroy (dialog);
2043 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2046 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2047 ModestMsgEditWindowPrivate *priv;
2048 GtkWidget *dialog = NULL;
2050 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2051 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2053 dialog = hildon_color_chooser_new ();
2054 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2055 g_free (buffer_format);
2057 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2059 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2060 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2063 gtk_widget_destroy (dialog);
2068 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2071 ModestMsgEditWindowPrivate *priv;
2072 GtkWidget *dialog = NULL;
2073 GdkColor *old_color = NULL;
2075 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2076 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2078 dialog = hildon_color_chooser_new ();
2079 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2081 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2083 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2084 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2086 gtk_widget_destroy (dialog);
2089 #endif /*!MODEST_HILDON_VERSION_0*/
2093 static TnyStream* create_stream_for_uri (const gchar* uri)
2098 TnyStream *result = NULL;
2100 GnomeVFSHandle *handle = NULL;
2101 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2102 if (test == GNOME_VFS_OK) {
2103 /* Create the tinymail stream: */
2104 /* Presumably tinymai will call gnome_vfs_close (handle) later. */
2105 result = TNY_STREAM (tny_vfs_stream_new (handle));
2112 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2115 ModestMsgEditWindowPrivate *priv;
2116 GtkWidget *dialog = NULL;
2118 GSList *uris = NULL;
2119 GSList *uri_node = NULL;
2121 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2123 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2124 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2125 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2127 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2129 response = gtk_dialog_run (GTK_DIALOG (dialog));
2131 case GTK_RESPONSE_OK:
2132 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2137 gtk_widget_destroy (dialog);
2139 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2141 GnomeVFSHandle *handle = NULL;
2142 GnomeVFSResult result;
2143 GtkTextIter position;
2144 GtkTextMark *insert_mark;
2146 uri = (const gchar *) uri_node->data;
2147 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2148 if (result == GNOME_VFS_OK) {
2150 GnomeVFSFileInfo *info;
2151 gchar *filename, *basename, *escaped_filename;
2152 TnyMimePart *mime_part;
2154 const gchar *mime_type = NULL;
2155 GnomeVFSURI *vfs_uri;
2156 guint64 stream_size;
2158 vfs_uri = gnome_vfs_uri_new (uri);
2160 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2161 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2162 g_free (escaped_filename);
2163 gnome_vfs_uri_unref (vfs_uri);
2164 info = gnome_vfs_file_info_new ();
2166 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2167 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2169 mime_type = gnome_vfs_file_info_get_mime_type (info);
2171 mime_part = tny_platform_factory_new_mime_part
2172 (modest_runtime_get_platform_factory ());
2174 TnyStream *stream = create_stream_for_uri (uri);
2175 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2177 content_id = g_strdup_printf ("%d", priv->last_cid);
2178 tny_mime_part_set_content_id (mime_part, content_id);
2179 g_free (content_id);
2182 basename = g_path_get_basename (filename);
2183 tny_mime_part_set_filename (mime_part, basename);
2186 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
2188 if (pixbuf != NULL) {
2189 priv->images_size += stream_size;
2190 priv->images_count ++;
2191 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2192 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2193 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
2196 tny_list_prepend (priv->images, (GObject *) mime_part);
2197 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2199 g_object_unref (mime_part);
2200 gnome_vfs_file_info_unref (info);
2209 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2211 GtkWidget *dialog = NULL;
2213 GSList *uris = NULL;
2216 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2217 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2218 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2220 response = gtk_dialog_run (GTK_DIALOG (dialog));
2222 case GTK_RESPONSE_OK:
2223 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2228 gtk_widget_destroy (dialog);
2230 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2231 const gchar *uri = (const gchar *) uri_node->data;
2232 modest_msg_edit_window_attach_file_one (window, uri);
2234 g_slist_foreach (uris, (GFunc) g_free, NULL);
2235 g_slist_free (uris);
2239 modest_msg_edit_window_attach_file_one (
2240 ModestMsgEditWindow *window,
2243 GnomeVFSHandle *handle = NULL;
2244 ModestMsgEditWindowPrivate *priv;
2245 GnomeVFSResult result;
2247 g_return_if_fail (window);
2248 g_return_if_fail (uri);
2250 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2252 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2253 if (result == GNOME_VFS_OK) {
2254 TnyMimePart *mime_part;
2256 const gchar *mime_type = NULL;
2258 gchar *escaped_filename;
2261 GnomeVFSFileInfo *info;
2262 GnomeVFSURI *vfs_uri;
2264 vfs_uri = gnome_vfs_uri_new (uri);
2267 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2268 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2269 g_free (escaped_filename);
2270 gnome_vfs_uri_unref (vfs_uri);
2272 info = gnome_vfs_file_info_new ();
2274 if (gnome_vfs_get_file_info (uri,
2276 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2278 mime_type = gnome_vfs_file_info_get_mime_type (info);
2279 mime_part = tny_platform_factory_new_mime_part
2280 (modest_runtime_get_platform_factory ());
2281 stream = TNY_STREAM (tny_vfs_stream_new (handle));
2283 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2285 g_object_unref (stream);
2287 content_id = g_strdup_printf ("%d", priv->last_cid);
2288 tny_mime_part_set_content_id (mime_part, content_id);
2289 g_free (content_id);
2292 basename = g_path_get_basename (filename);
2293 tny_mime_part_set_filename (mime_part, basename);
2296 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2297 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2299 info->size == 0, info->size);
2300 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2301 gtk_widget_show_all (priv->attachments_caption);
2302 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2304 g_object_unref (mime_part);
2305 gnome_vfs_file_info_unref (info);
2310 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2313 ModestMsgEditWindowPrivate *priv;
2316 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2317 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2319 if (att_list == NULL) {
2320 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2322 g_object_ref (att_list);
2325 if (tny_list_get_length (att_list) == 0) {
2326 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2328 GtkWidget *confirmation_dialog = NULL;
2329 gboolean dialog_response;
2330 gchar *message = NULL;
2331 gchar *filename = NULL;
2333 if (tny_list_get_length (att_list) == 1) {
2335 iter = tny_list_create_iterator (att_list);
2336 part = (TnyMimePart *) tny_iterator_get_current (iter);
2337 g_object_unref (iter);
2338 if (TNY_IS_MSG (part)) {
2339 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2341 filename = g_strdup (tny_header_get_subject (header));
2342 g_object_unref (header);
2344 if (filename == NULL) {
2345 filename = g_strdup (_("mail_va_no_subject"));
2348 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2350 g_object_unref (part);
2352 filename = g_strdup ("");
2354 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
2355 (tny_list_get_length (att_list) == 1)), filename);
2357 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
2359 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
2360 gtk_widget_destroy (confirmation_dialog);
2361 if (!dialog_response) {
2362 g_object_unref (att_list);
2365 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
2367 for (iter = tny_list_create_iterator (att_list);
2368 !tny_iterator_is_done (iter);
2369 tny_iterator_next (iter)) {
2370 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2371 const gchar *att_id;
2372 tny_list_remove (priv->attachments, (GObject *) mime_part);
2374 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2376 if (tny_list_get_length (priv->attachments) == 0)
2377 gtk_widget_hide (priv->attachments_caption);
2378 att_id = tny_mime_part_get_content_id (mime_part);
2380 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2382 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2383 g_object_unref (mime_part);
2385 g_object_unref (iter);
2388 g_object_unref (att_list);
2390 /* if the last attachment has been removed, focus the Subject: field */
2391 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2392 gtk_widget_grab_focus (priv->subject_field);
2396 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2399 ModestMsgEditWindowPrivate *priv;
2400 GdkColor *new_color;
2401 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2403 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2404 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2407 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2409 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2411 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2413 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2418 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
2421 ModestMsgEditWindowPrivate *priv;
2422 gint new_size_index;
2423 ModestMsgEditWindow *window;
2426 window = MODEST_MSG_EDIT_WINDOW (userdata);
2427 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2428 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2430 if (gtk_check_menu_item_get_active (menu_item)) {
2432 WPTextBufferFormat format;
2434 memset (&format, 0, sizeof (format));
2435 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2437 label = gtk_bin_get_child (GTK_BIN (menu_item));
2439 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
2440 format.cs.font_size = TRUE;
2441 format.cs.text_position = TRUE;
2442 format.cs.font = TRUE;
2443 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
2444 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2446 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2447 GINT_TO_POINTER (wp_get_font_size_index (new_size_index, 12))))
2448 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2450 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2451 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
2452 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2458 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
2461 ModestMsgEditWindowPrivate *priv;
2462 gint new_font_index;
2463 ModestMsgEditWindow *window;
2466 window = MODEST_MSG_EDIT_WINDOW (userdata);
2467 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2468 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2470 if (gtk_check_menu_item_get_active (menu_item)) {
2473 label = gtk_bin_get_child (GTK_BIN (menu_item));
2475 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
2477 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2478 GINT_TO_POINTER(new_font_index)))
2479 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2481 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2482 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2483 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2489 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
2491 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
2492 ModestWindowPrivate *parent_priv;
2493 ModestWindowMgr *mgr;
2494 gboolean is_fullscreen;
2495 GtkAction *fs_toggle_action;
2498 mgr = modest_runtime_get_window_mgr ();
2499 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
2501 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
2503 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2504 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2505 if (is_fullscreen != active)
2506 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2514 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2517 ModestMsgEditWindowPrivate *priv = NULL;
2518 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2520 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2521 if (!priv->update_caption_visibility)
2524 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2526 gtk_widget_show (priv->cc_caption);
2528 gtk_widget_hide (priv->cc_caption);
2530 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2534 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2537 ModestMsgEditWindowPrivate *priv = NULL;
2538 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2540 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2541 if (!priv->update_caption_visibility)
2544 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2546 gtk_widget_show (priv->bcc_caption);
2548 gtk_widget_hide (priv->bcc_caption);
2550 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2554 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2555 ModestRecptEditor *editor)
2557 ModestMsgEditWindowPrivate *priv;
2559 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2560 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2561 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2563 if (editor == NULL) {
2564 GtkWidget *view_focus;
2565 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2567 /* This code should be kept in sync with ModestRecptEditor. The
2568 textview inside the recpt editor is the one that really gets the
2569 focus. As it's inside a scrolled window, and this one inside the
2570 hbox recpt editor inherits from, we'll need to go up in the
2571 hierarchy to know if the text view is part of the recpt editor
2572 or if it's a different text entry */
2574 if (gtk_widget_get_parent (view_focus)) {
2575 GtkWidget *first_parent;
2577 first_parent = gtk_widget_get_parent (view_focus);
2578 if (gtk_widget_get_parent (first_parent) &&
2579 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2580 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2585 editor = MODEST_RECPT_EDITOR (priv->to_field);
2589 modest_address_book_select_addresses (editor);
2594 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2596 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2598 modest_msg_edit_window_open_addressbook (window, NULL);
2602 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2603 gboolean show_toolbar)
2605 ModestWindowPrivate *parent_priv;
2606 const gchar *action_name;
2609 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2610 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2612 /* We can not just use the code of
2613 modest_msg_edit_window_setup_toolbar because it has a
2614 mixture of both initialization and creation code. */
2616 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2618 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2620 /* Update also the actions (to update the toggles in the
2621 menus), we have to do it manually because some other window
2622 of the same time could have changed it (remember that the
2623 toolbar fullscreen mode is shared by all the windows of the
2625 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
2626 action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarFullScreenMenu";
2628 action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarNormalScreenMenu";
2630 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
2631 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
2637 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2638 TnyHeaderFlags priority_flags)
2640 ModestMsgEditWindowPrivate *priv;
2641 ModestWindowPrivate *parent_priv;
2643 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2645 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2646 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2648 if (priv->priority_flags != priority_flags) {
2649 GtkAction *priority_action = NULL;
2651 priv->priority_flags = priority_flags;
2653 switch (priority_flags) {
2654 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2655 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2656 gtk_widget_show (priv->priority_icon);
2657 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2658 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2660 case TNY_HEADER_FLAG_LOW_PRIORITY:
2661 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2662 gtk_widget_show (priv->priority_icon);
2663 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2664 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2667 gtk_widget_hide (priv->priority_icon);
2668 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2669 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2672 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2673 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2678 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2681 ModestMsgEditWindowPrivate *priv;
2682 ModestWindowPrivate *parent_priv;
2683 gint current_format;
2685 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2687 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2688 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2690 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2691 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2693 if (current_format != file_format) {
2694 switch (file_format) {
2695 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2696 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2697 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
2699 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2703 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2704 response = gtk_dialog_run (GTK_DIALOG (dialog));
2705 gtk_widget_destroy (dialog);
2706 if (response == GTK_RESPONSE_OK) {
2707 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2709 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2710 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
2715 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2720 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2723 ModestMsgEditWindowPrivate *priv;
2724 WPTextBufferFormat oldfmt, fmt;
2725 gint old_position = 0;
2729 GdkColor *color = NULL;
2730 gboolean bold, bold_set, italic, italic_set;
2731 gboolean underline, underline_set;
2732 gboolean strikethrough, strikethrough_set;
2733 gboolean position_set;
2734 gboolean font_size_set, font_set, color_set;
2737 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2738 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2740 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2742 /* First we get the currently selected font information */
2743 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2745 switch (oldfmt.text_position) {
2746 case TEXT_POSITION_NORMAL:
2749 case TEXT_POSITION_SUPERSCRIPT:
2757 g_object_set (G_OBJECT (dialog),
2758 "bold", oldfmt.bold != FALSE,
2759 "bold-set", !oldfmt.cs.bold,
2760 "underline", oldfmt.underline != FALSE,
2761 "underline-set", !oldfmt.cs.underline,
2762 "italic", oldfmt.italic != FALSE,
2763 "italic-set", !oldfmt.cs.italic,
2764 "strikethrough", oldfmt.strikethrough != FALSE,
2765 "strikethrough-set", !oldfmt.cs.strikethrough,
2766 "color", &oldfmt.color,
2767 "color-set", !oldfmt.cs.color,
2768 "size", wp_font_size[oldfmt.font_size],
2769 "size-set", !oldfmt.cs.font_size,
2770 "position", old_position,
2771 "position-set", !oldfmt.cs.text_position,
2772 "family", wp_get_font_name (oldfmt.font),
2773 "family-set", !oldfmt.cs.font,
2776 gtk_widget_show_all (dialog);
2777 response = gtk_dialog_run (GTK_DIALOG (dialog));
2778 if (response == GTK_RESPONSE_OK) {
2780 g_object_get( dialog,
2782 "bold-set", &bold_set,
2783 "underline", &underline,
2784 "underline-set", &underline_set,
2786 "italic-set", &italic_set,
2787 "strikethrough", &strikethrough,
2788 "strikethrough-set", &strikethrough_set,
2790 "color-set", &color_set,
2792 "size-set", &font_size_set,
2793 "family", &font_name,
2794 "family-set", &font_set,
2795 "position", &position,
2796 "position-set", &position_set,
2801 if (response == GTK_RESPONSE_OK) {
2802 memset(&fmt, 0, sizeof(fmt));
2808 fmt.italic = italic;
2809 fmt.cs.italic = TRUE;
2811 if (underline_set) {
2812 fmt.underline = underline;
2813 fmt.cs.underline = TRUE;
2815 if (strikethrough_set) {
2816 fmt.strikethrough = strikethrough;
2817 fmt.cs.strikethrough = TRUE;
2822 ? TEXT_POSITION_NORMAL
2823 : ( ( position == 1 )
2824 ? TEXT_POSITION_SUPERSCRIPT
2825 : TEXT_POSITION_SUBSCRIPT );
2826 fmt.cs.text_position = TRUE;
2827 fmt.font_size = oldfmt.font_size;
2831 fmt.cs.color = TRUE;
2834 fmt.font = wp_get_font_index(font_name,
2839 if (font_size_set) {
2840 fmt.cs.font_size = TRUE;
2841 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
2843 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2844 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2846 gtk_widget_destroy (dialog);
2848 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2852 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2854 ModestMsgEditWindowPrivate *priv;
2856 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2857 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2859 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2861 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2862 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2867 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2869 ModestMsgEditWindowPrivate *priv;
2871 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2872 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2874 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2876 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2877 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2882 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2884 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2886 priv->can_undo = can_undo;
2890 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2892 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2894 priv->can_redo = can_redo;
2898 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
2900 ModestMsgEditWindowPrivate *priv;
2901 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2902 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2904 return priv->can_undo;
2908 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
2910 ModestMsgEditWindowPrivate *priv;
2911 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2912 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2914 return priv->can_redo;
2919 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2922 GtkTextIter match_start, match_end;
2924 if (image_id == NULL)
2927 gtk_text_buffer_get_start_iter (buffer, &iter);
2929 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2930 GSList *tags = gtk_text_iter_get_tags (&match_start);
2932 for (node = tags; node != NULL; node = g_slist_next (node)) {
2933 GtkTextTag *tag = (GtkTextTag *) node->data;
2934 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2935 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2936 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2938 offset = gtk_text_iter_get_offset (&match_start);
2939 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2940 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2944 gtk_text_iter_forward_char (&iter);
2949 message_is_empty (ModestMsgEditWindow *window)
2951 ModestMsgEditWindowPrivate *priv = NULL;
2953 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2954 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2956 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
2957 * so we can ignore markup.
2959 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
2962 count = gtk_text_buffer_get_char_count (buf);
2968 msg_body_focus (GtkWidget *focus,
2969 GdkEventFocus *event,
2973 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
2974 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
2975 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
2980 recpt_field_changed (GtkTextBuffer *buffer,
2981 ModestMsgEditWindow *editor)
2983 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
2984 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
2988 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
2990 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
2991 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
2995 modest_msg_edit_window_reset_modified (ModestMsgEditWindow *editor)
2997 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2998 GtkTextBuffer *buffer;
3000 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3001 gtk_text_buffer_set_modified (buffer, FALSE);
3002 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3003 gtk_text_buffer_set_modified (buffer, FALSE);
3004 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3005 gtk_text_buffer_set_modified (buffer, FALSE);
3006 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
3010 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3012 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3013 GtkTextBuffer *buffer;
3015 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3016 if (gtk_text_buffer_get_modified (buffer))
3018 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3019 if (gtk_text_buffer_get_modified (buffer))
3021 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3022 if (gtk_text_buffer_get_modified (buffer))
3024 if (gtk_text_buffer_get_modified (priv->text_buffer))
3034 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3036 ModestMsgEditWindowPrivate *priv = NULL;
3038 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3039 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3041 /* check if there's no recipient added */
3042 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3043 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3044 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3045 /* no recipient contents, then select contacts */
3046 modest_msg_edit_window_open_addressbook (window, NULL);
3050 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3051 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3054 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3055 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3058 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3059 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3063 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3064 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3065 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3072 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3073 ModestMsgEditWindow *window)
3075 modest_msg_edit_window_offer_attach_file (window);
3079 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3081 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3083 return priv->clipboard_text;
3087 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3089 ModestMsgEditWindow *window)
3091 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3092 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3094 if (!GTK_WIDGET_VISIBLE (window))
3097 text = gtk_clipboard_wait_for_text (selection_clipboard);
3099 if (priv->clipboard_text != NULL) {
3100 g_free (priv->clipboard_text);
3102 priv->clipboard_text = text;
3104 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3107 subject_field_move_cursor (GtkEntry *entry,
3108 GtkMovementStep step,
3113 if (!GTK_WIDGET_VISIBLE (window))
3116 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3120 update_window_title (ModestMsgEditWindow *window)
3122 ModestMsgEditWindowPrivate *priv = NULL;
3123 const gchar *subject;
3125 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3126 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3127 if (subject == NULL || subject[0] == '\0')
3128 subject = _("mail_va_new_email");
3130 gtk_window_set_title (GTK_WINDOW (window), subject);
3135 subject_field_changed (GtkEditable *editable,
3136 ModestMsgEditWindow *window)
3138 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3139 update_window_title (window);
3140 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3141 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3142 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3146 subject_field_insert_text (GtkEditable *editable,
3148 gint new_text_length,
3150 ModestMsgEditWindow *window)
3152 GString *result = g_string_new ("");
3154 gint result_len = 0;
3155 const gchar *entry_text = NULL;
3158 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3159 old_length = g_utf8_strlen (entry_text, -1);
3161 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3162 gunichar c = g_utf8_get_char_validated (current, 8);
3163 /* Invalid unichar, stop */
3169 result = g_string_append_unichar (result, c);
3173 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3174 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3177 /* Prevent endless recursion */
3178 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3179 g_signal_emit_by_name (editable, "insert-text",
3180 (gpointer) result->str, (gpointer) result->len,
3181 (gpointer) position, (gpointer) window);
3182 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3186 if (result_len + old_length > 1000) {
3187 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3188 dgettext("hildon-common-strings",
3189 "ckdg_ib_maximum_characters_reached"));
3192 g_string_free (result, TRUE);
3196 text_buffer_insert_text (GtkTextBuffer *buffer,
3199 gint new_text_length,
3200 ModestMsgEditWindow *window)
3202 GString *result = g_string_new ("");
3204 gint result_len = 0;
3205 gboolean changed = FALSE;
3207 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3208 gunichar c = g_utf8_get_char_validated (current, 8);
3209 /* Invalid unichar, stop */
3215 result = g_string_append_c (result, ' ');
3219 result = g_string_append_unichar (result, c);
3225 g_signal_stop_emission_by_name (G_OBJECT (buffer), "insert-text");
3226 g_signal_handlers_block_by_func(G_OBJECT(buffer), G_CALLBACK(text_buffer_insert_text), window);
3227 g_signal_emit_by_name (buffer, "insert-text",
3229 (gpointer) result->str, (gpointer) result->len,
3231 g_signal_handlers_unblock_by_func(G_OBJECT(buffer), G_CALLBACK(text_buffer_insert_text), window);
3234 g_string_free (result, TRUE);
3238 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3241 ModestMsgEditWindowPrivate *priv = NULL;
3243 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3244 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3246 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3249 gtk_widget_show_all (priv->find_toolbar);
3250 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3252 gtk_widget_hide_all (priv->find_toolbar);
3253 gtk_widget_grab_focus (priv->msg_body);
3259 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3261 GtkTextIter *match_start,
3262 GtkTextIter *match_end)
3264 GtkTextIter end_iter;
3265 gchar *str_casefold;
3268 gchar *range_casefold;
3271 gboolean result = FALSE;
3278 gtk_text_iter_forward_to_end (&end_iter);
3280 str_casefold = g_utf8_casefold (str, -1);
3281 str_chars_n = strlen (str);
3283 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3284 range_casefold = g_utf8_casefold (range_text, -1);
3285 range_chars_n = strlen (range_casefold);
3287 if (range_chars_n < str_chars_n) {
3288 g_free (str_casefold);
3289 g_free (range_text);
3290 g_free (range_casefold);
3294 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3295 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3296 if (!g_utf8_collate (range_subtext, str_casefold)) {
3297 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3299 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3300 match_start, match_end, NULL);
3301 g_free (found_text);
3303 g_free (range_subtext);
3307 g_free (str_casefold);
3308 g_free (range_text);
3309 g_free (range_casefold);
3316 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3317 ModestMsgEditWindow *window)
3319 gchar *current_search = NULL;
3320 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3322 GtkTextIter selection_start, selection_end;
3323 GtkTextIter match_start, match_end;
3324 gboolean continue_search = FALSE;
3326 if (message_is_empty (window)) {
3327 g_free (priv->last_search);
3328 priv->last_search = NULL;
3329 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3333 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3334 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3335 g_free (current_search);
3336 g_free (priv->last_search);
3337 priv->last_search = NULL;
3338 /* Information banner about empty search */
3339 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
3343 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3344 continue_search = TRUE;
3346 g_free (priv->last_search);
3347 priv->last_search = g_strdup (current_search);
3350 if (continue_search) {
3351 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3352 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3353 &match_start, &match_end);
3355 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
3357 GtkTextIter buffer_start;
3358 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3359 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3360 &match_start, &match_end);
3362 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
3365 /* Mark as selected the string found in search */
3367 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3368 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3370 g_free (priv->last_search);
3371 priv->last_search = NULL;
3373 g_free (current_search);
3377 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3378 ModestMsgEditWindow *window)
3380 GtkToggleAction *toggle;
3381 ModestWindowPrivate *parent_priv;
3382 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3384 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
3385 gtk_toggle_action_set_active (toggle, FALSE);
3389 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3391 ModestMsgEditWindowPrivate *priv;
3393 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3398 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3401 ModestMsgEditWindowPrivate *priv;
3403 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3409 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3412 ModestMsgEditWindowPrivate *priv;
3413 TnyHeader *header = NULL;
3415 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3416 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3418 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3419 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3421 if (priv->draft_msg != NULL) {
3422 g_object_unref (priv->draft_msg);
3425 if (draft != NULL) {
3426 g_object_ref (draft);
3427 header = tny_msg_get_header (draft);
3428 if (priv->msg_uid) {
3429 g_free (priv->msg_uid);
3430 priv->msg_uid = NULL;
3432 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3433 if (GTK_WIDGET_REALIZED (window))
3434 modest_window_mgr_register_window (mgr, MODEST_WINDOW (window));
3437 priv->draft_msg = draft;
3441 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3442 GtkTextIter *start, GtkTextIter *end,
3445 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3446 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3449 if (tag == NULL+13) return;
3450 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3451 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3452 replace_with_images (window, priv->images);
3457 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3460 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3462 g_return_if_fail (TNY_IS_MIME_PART (part));
3463 tny_list_prepend (priv->attachments, (GObject *) part);
3464 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3465 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3466 gtk_widget_show_all (priv->attachments_caption);
3467 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3471 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3473 ModestMsgEditWindowPrivate *priv;
3475 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3476 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3478 return priv->msg_uid;
3482 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3483 ModestMsgEditWindowWidgetType widget_type)
3485 ModestMsgEditWindowPrivate *priv;
3487 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3488 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3490 switch (widget_type) {
3491 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3492 return priv->msg_body;
3494 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3495 return priv->to_field;
3497 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3498 return priv->cc_field;
3500 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3501 return priv->bcc_field;
3503 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3504 return priv->subject_field;
3506 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3507 return priv->attachments_view;
3515 remove_tags (WPTextBuffer *buffer)
3517 GtkTextIter start, end;
3519 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3520 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3522 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3526 on_account_removed (TnyAccountStore *account_store,
3527 TnyAccount *account,
3530 /* Do nothing if it's a store account, because we use the
3531 transport to send the messages */
3532 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3533 const gchar *parent_acc = NULL;
3534 const gchar *our_acc = NULL;
3536 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3537 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3538 /* Close this window if I'm showing a message of the removed account */
3539 if (strcmp (parent_acc, our_acc) == 0)
3540 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3545 on_zoom_minus_plus_not_implemented (ModestWindow *window)
3547 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3549 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
3555 set_zoom_do_nothing (ModestWindow *window,
3561 get_zoom_do_nothing (ModestWindow *window)