1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37 #include <tny-vfs-stream.h>
41 #include <modest-account-mgr.h>
42 #include <modest-account-mgr-helpers.h>
44 #include <widgets/modest-msg-edit-window.h>
45 #include <widgets/modest-combo-box.h>
46 #include <widgets/modest-recpt-editor.h>
47 #include <widgets/modest-attachments-view.h>
49 #include <modest-runtime.h>
51 #include "modest-platform.h"
52 #include "modest-icon-names.h"
53 #include "modest-widget-memory.h"
54 #include "modest-window-priv.h"
55 #include "modest-mail-operation.h"
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-tny-folder.h"
59 #include "modest-tny-account.h"
60 #include "modest-address-book.h"
61 #include "modest-text-utils.h"
62 #include <tny-simple-list.h>
63 #include <wptextview.h>
64 #include <wptextbuffer.h>
65 #include "modest-scroll-area.h"
66 #include "modest-msg-edit-window-ui-dimming.h"
68 #include "modest-hildon-includes.h"
69 #ifdef MODEST_HAVE_HILDON0_WIDGETS
70 #include <hildon-widgets/hildon-color-chooser.h>
72 #include "widgets/modest-msg-edit-window-ui.h"
73 #ifdef MODEST_HAVE_HILDON0_WIDGETS
74 #include <libgnomevfs/gnome-vfs-mime-utils.h>
76 #include <libgnomevfs/gnome-vfs-mime.h>
78 #include <modest-utils.h>
79 #include "modest-maemo-utils.h"
82 #define DEFAULT_FONT_SIZE 3
83 #define DEFAULT_FONT 2
84 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
85 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
86 #define DEFAULT_MAIN_VBOX_SPACING 6
87 #define SUBJECT_MAX_LENGTH 1000
88 #define IMAGE_MAX_WIDTH 560
89 #define DEFAULT_FONT_SCALE 1.5
91 static gboolean is_wp_text_buffer_started = FALSE;
93 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
94 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
95 static void modest_msg_edit_window_finalize (GObject *obj);
97 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
98 static void body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
99 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
101 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
102 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
103 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
104 static void text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
105 GtkTextIter *start, GtkTextIter *end,
107 static void text_buffer_insert_text (GtkTextBuffer *buffer,
108 GtkTextIter *location,
111 ModestMsgEditWindow *window);
112 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
113 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
114 static void subject_field_insert_text (GtkEditable *editable,
116 gint new_text_length,
118 ModestMsgEditWindow *window);
119 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
121 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
123 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
125 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
126 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
127 GdkEventWindowState *event,
129 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
130 ModestRecptEditor *editor);
131 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
132 ModestMsgEditWindow *window);
134 /* ModestWindow methods implementation */
135 static void modest_msg_edit_window_disconnect_signals (ModestWindow *window);
136 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
137 gboolean show_toolbar);
138 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
140 ModestMsgEditWindow *window);
141 static void subject_field_move_cursor (GtkEntry *entry,
142 GtkMovementStep step,
146 static void update_window_title (ModestMsgEditWindow *window);
149 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
150 ModestMsgEditWindow *window);
151 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
152 ModestMsgEditWindow *window);
153 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
155 GtkTextIter *match_start,
156 GtkTextIter *match_end);
158 static void remove_tags (WPTextBuffer *buffer);
160 static void on_account_removed (TnyAccountStore *account_store,
164 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
165 static void set_zoom_do_nothing (ModestWindow *window, gdouble zoom);
166 static gdouble get_zoom_do_nothing (ModestWindow *window);
168 static void init_window (ModestMsgEditWindow *obj);
170 gboolean scroll_drag_timeout (gpointer userdata);
171 static void correct_scroll (ModestMsgEditWindow *w);
172 static void correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused);
173 static void text_buffer_end_user_action (GtkTextBuffer *buffer,
174 ModestMsgEditWindow *userdata);
175 static void text_buffer_mark_set (GtkTextBuffer *buffer,
178 ModestMsgEditWindow *userdata);
179 void vadj_changed (GtkAdjustment *adj,
180 ModestMsgEditWindow *window);
182 static ModestPair *find_transport_from_message_sender (ModestPairList *transports,
188 static void DEBUG_BUFFER (WPTextBuffer *buffer)
192 g_message ("BEGIN BUFFER OF SIZE %d", gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (buffer)));
194 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
195 while (!gtk_text_iter_is_end (&iter)) {
196 GString *output = g_string_new ("");
197 GSList *toggled_tags;
200 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
201 g_string_append_printf (output, "%d: CLOSED [ ", gtk_text_iter_get_offset (&iter));
202 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
203 GtkTextTag *tag = (GtkTextTag *) node->data;
205 g_object_get (G_OBJECT (tag), "name", &name, NULL);
206 output = g_string_append (output, name);
207 g_string_append (output, " ");
209 output = g_string_append (output, "] OPENED [ ");
210 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
211 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
212 GtkTextTag *tag = (GtkTextTag *) node->data;
214 g_object_get (G_OBJECT (tag), "name", &name, NULL);
215 output = g_string_append (output, name);
216 g_string_append (output, " ");
218 output = g_string_append (output, "]\n");
219 g_message ("%s", output->str);
220 g_string_free (output, TRUE);
221 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
223 g_message ("END BUFFER");
228 /* static gboolean */
229 /* on_key_pressed (GtkWidget *self, */
230 /* GdkEventKey *event, */
231 /* gpointer user_data); */
233 /* list my signals */
240 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
241 struct _ModestMsgEditWindowPrivate {
244 GtkWidget *header_box;
246 ModestPairList *from_field_protos;
247 GtkWidget *from_field;
248 const gchar *original_account_name;
252 GtkWidget *bcc_field;
253 GtkWidget *subject_field;
254 GtkWidget *attachments_view;
255 GtkWidget *priority_icon;
256 GtkWidget *add_attachment_button;
258 GtkWidget *cc_caption;
259 GtkWidget *bcc_caption;
260 gboolean update_caption_visibility;
261 GtkWidget *attachments_caption;
263 GtkTextBuffer *text_buffer;
265 GtkWidget *font_size_toolitem;
266 GtkWidget *font_face_toolitem;
267 GtkWidget *font_color_button;
268 GSList *font_items_group;
269 GtkWidget *font_tool_button_label;
270 GSList *size_items_group;
271 GtkWidget *size_tool_button_label;
273 GtkWidget *find_toolbar;
277 guint scroll_drag_timeout_id;
281 TnyList *attachments;
286 TnyHeaderFlags priority_flags;
288 gboolean can_undo, can_redo;
289 gulong clipboard_change_handler_id;
290 gulong default_clipboard_change_handler_id;
291 gulong account_removed_handler_id;
292 gchar *clipboard_text;
301 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
302 MODEST_TYPE_MSG_EDIT_WINDOW, \
303 ModestMsgEditWindowPrivate))
305 static GtkWindowClass *parent_class = NULL;
307 /* uncomment the following if you have defined any signals */
308 /* static guint signals[LAST_SIGNAL] = {0}; */
311 modest_msg_edit_window_get_type (void)
313 static GType my_type = 0;
315 static const GTypeInfo my_info = {
316 sizeof(ModestMsgEditWindowClass),
317 NULL, /* base init */
318 NULL, /* base finalize */
319 (GClassInitFunc) modest_msg_edit_window_class_init,
320 NULL, /* class finalize */
321 NULL, /* class data */
322 sizeof(ModestMsgEditWindow),
324 (GInstanceInitFunc) modest_msg_edit_window_init,
327 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
328 "ModestMsgEditWindow",
336 save_state (ModestWindow *self)
338 modest_widget_memory_save (modest_runtime_get_conf(),
339 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
344 restore_settings (ModestMsgEditWindow *self)
346 ModestConf *conf = NULL;
348 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
350 conf = modest_runtime_get_conf ();
351 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
352 "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarNormalScreenMenu");
353 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
354 modest_conf_get_bool (conf, MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR, NULL));
355 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
356 "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarFullScreenMenu");
357 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
358 modest_conf_get_bool (conf, MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
360 /* set initial state of cc and bcc */
361 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
362 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
363 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
364 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
365 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
366 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
368 /* Dim at start clipboard actions */
369 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
370 gtk_action_set_sensitive (action, FALSE);
371 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
372 gtk_action_set_sensitive (action, FALSE);
373 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
374 gtk_action_set_sensitive (action, FALSE);
376 modest_widget_memory_restore (conf,
377 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
382 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
384 GObjectClass *gobject_class;
385 ModestWindowClass *modest_window_class;
386 gobject_class = (GObjectClass*) klass;
387 modest_window_class = (ModestWindowClass*) klass;
389 parent_class = g_type_class_peek_parent (klass);
390 gobject_class->finalize = modest_msg_edit_window_finalize;
392 modest_window_class->set_zoom_func = set_zoom_do_nothing;
393 modest_window_class->get_zoom_func = get_zoom_do_nothing;
394 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
395 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
396 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
397 modest_window_class->save_state_func = save_state;
398 modest_window_class->disconnect_signals_func = modest_msg_edit_window_disconnect_signals;
400 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
404 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
406 ModestMsgEditWindowPrivate *priv;
407 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
409 priv->msg_body = NULL;
411 priv->from_field = NULL;
412 priv->to_field = NULL;
413 priv->cc_field = NULL;
414 priv->bcc_field = NULL;
415 priv->subject_field = NULL;
416 priv->attachments = TNY_LIST (tny_simple_list_new ());
417 priv->images = TNY_LIST (tny_simple_list_new ());
418 priv->images_size = 0;
419 priv->images_count = 0;
422 priv->cc_caption = NULL;
423 priv->bcc_caption = NULL;
424 priv->update_caption_visibility = FALSE;
426 priv->priority_flags = 0;
428 priv->find_toolbar = NULL;
429 priv->last_search = NULL;
431 priv->draft_msg = NULL;
432 priv->outbox_msg = NULL;
433 priv->msg_uid = NULL;
435 priv->can_undo = FALSE;
436 priv->can_redo = FALSE;
437 priv->clipboard_change_handler_id = 0;
438 priv->default_clipboard_change_handler_id = 0;
439 priv->account_removed_handler_id = 0;
440 priv->clipboard_text = NULL;
443 priv->scroll_drag_timeout_id = 0;
444 priv->last_upper = 0.0;
446 modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
447 GTK_WINDOW(obj),"applications_email_editor");
449 if (!is_wp_text_buffer_started) {
450 is_wp_text_buffer_started = TRUE;
451 wp_text_buffer_library_init ();
456 hildon_program_add_window (hildon_program_get_instance(),
461 /* FIXME: this is a dup from the one in gtk/ */
464 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
466 static ModestPairList*
467 get_transports (void)
469 GSList *transports = NULL;
471 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
472 GSList *accounts = modest_account_mgr_account_names (account_mgr,
473 TRUE /* only enabled accounts. */);
475 GSList *cursor = accounts;
477 gchar *account_name = cursor->data;
478 gchar *from_string = NULL;
480 from_string = modest_account_mgr_get_from_string (account_mgr,
484 if (from_string && account_name) {
485 gchar *name = account_name;
486 ModestPair *pair = modest_pair_new ((gpointer) name,
487 (gpointer) from_string , TRUE);
488 transports = g_slist_prepend (transports, pair);
491 cursor = cursor->next;
493 g_slist_free (accounts); /* only free the accounts, not the elements,
494 * because they are used in the pairlist */
499 * Search an (account, address) ModestPairList for a pair whose
500 * address matches the one in the From: header of a TnyMsg
502 * @result: A ModestPair * with a matching address, or NULL if none found
505 find_transport_from_message_sender (ModestPairList *transports, TnyMsg *msg)
507 g_return_val_if_fail (transports, NULL);
508 g_return_val_if_fail (msg, NULL);
510 ModestPair *account_pair = NULL;
511 TnyHeader *header = tny_msg_get_header (msg);
513 if (header != NULL && tny_header_get_from (header)) {
514 char *from_addr = modest_text_utils_get_email_address (tny_header_get_from (header));
516 for (iter = transports; iter && !account_pair; iter = iter->next) {
517 ModestPair *pair = (ModestPair *) iter->data;
518 char *account_addr = modest_text_utils_get_email_address ((char *) pair->second);
519 if (account_addr && !strcasecmp(from_addr, account_addr)) {
522 g_free (account_addr);
528 g_object_unref (header);
533 static void window_focus (GtkWindow *window,
537 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
541 scroll_drag_timeout (gpointer userdata)
543 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
544 ModestMsgEditWindowPrivate *priv;
546 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
548 correct_scroll_without_drag_check (win, TRUE);
550 priv->scroll_drag_timeout_id = 0;
556 correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused)
558 ModestMsgEditWindowPrivate *priv;
561 GdkRectangle rectangle;
567 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
569 if (only_if_focused && !gtk_widget_is_focus (priv->msg_body))
572 insert = gtk_text_buffer_get_insert (priv->text_buffer);
573 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
575 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
576 vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll));
577 offset = priv->msg_body->allocation.y;
579 new_value = vadj->value;
581 if ((offset + rectangle.y + rectangle.height) >
582 ((gint) (vadj->value +vadj->page_size))) {
583 new_value = (offset + rectangle.y) - vadj->page_size * 0.25;
584 if (new_value > vadj->upper - vadj->page_size)
585 new_value = vadj->upper - vadj->page_size;
586 } else if ((offset + rectangle.y) < ((gint) vadj->value)) {
587 new_value = (offset + rectangle.y - vadj->page_size * 0.75);
588 if (((gint) (new_value + vadj->page_size)) < (offset + rectangle.y + rectangle.height))
589 new_value = offset + rectangle.y + rectangle.height - (gint) vadj->page_size;
592 if (new_value > vadj->value)
593 new_value = vadj->value;
596 if (vadj->value != new_value) {
597 g_signal_emit_by_name (GTK_TEXT_VIEW(priv->msg_body)->layout,
599 vadj->value = new_value;
600 gtk_adjustment_value_changed (vadj);
601 /* invalidate body */
602 window = gtk_widget_get_parent_window (priv->msg_body);
604 gdk_window_invalidate_rect (window, NULL, TRUE);
610 correct_scroll (ModestMsgEditWindow *w)
612 ModestMsgEditWindowPrivate *priv;
614 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
615 if (gtk_grab_get_current () == priv->msg_body) {
616 if (priv->scroll_drag_timeout_id == 0) {
617 priv->scroll_drag_timeout_id = g_timeout_add (500, (GSourceFunc) scroll_drag_timeout,
623 correct_scroll_without_drag_check (w, TRUE);
627 text_buffer_end_user_action (GtkTextBuffer *buffer,
628 ModestMsgEditWindow *userdata)
631 correct_scroll (userdata);
635 text_buffer_mark_set (GtkTextBuffer *buffer,
638 ModestMsgEditWindow *userdata)
640 gtk_text_buffer_begin_user_action (buffer);
641 gtk_text_buffer_end_user_action (buffer);
645 cut_clipboard_check (GtkTextView *text_view,
648 GtkTextBuffer *buffer;
650 buffer = gtk_text_view_get_buffer (text_view);
651 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
652 g_signal_stop_emission_by_name ((gpointer )text_view, "cut-clipboard");
657 copy_clipboard_check (GtkTextView *text_view,
660 GtkTextBuffer *buffer;
662 buffer = gtk_text_view_get_buffer (text_view);
663 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
664 g_signal_stop_emission_by_name ((gpointer )text_view, "copy-clipboard");
668 void vadj_changed (GtkAdjustment *adj,
669 ModestMsgEditWindow *window)
671 ModestMsgEditWindowPrivate *priv;
673 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
675 if (priv->last_upper != adj->upper) {
676 priv->last_upper = adj->upper;
677 correct_scroll (window);
682 connect_signals (ModestMsgEditWindow *obj)
684 ModestMsgEditWindowPrivate *priv;
686 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
688 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
689 G_CALLBACK (text_buffer_refresh_attributes), obj);
690 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
691 G_CALLBACK (text_buffer_can_undo), obj);
692 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
693 G_CALLBACK (text_buffer_can_redo), obj);
694 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
695 G_CALLBACK (body_changed), obj);
696 g_signal_connect (G_OBJECT (priv->text_buffer), "modified-changed",
697 G_CALLBACK (body_changed), obj);
698 g_signal_connect (G_OBJECT (priv->text_buffer), "insert-text",
699 G_CALLBACK (text_buffer_insert_text), obj);
700 g_signal_connect (G_OBJECT (obj), "window-state-event",
701 G_CALLBACK (modest_msg_edit_window_window_state_event),
703 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
704 G_CALLBACK (text_buffer_end_user_action), obj);
705 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
706 G_CALLBACK (text_buffer_mark_set), obj);
707 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
708 G_CALLBACK (text_buffer_apply_tag), obj);
709 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
710 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
711 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
712 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
713 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
714 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
716 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
717 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
719 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
720 G_CALLBACK (msg_body_focus), obj);
721 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
722 G_CALLBACK (msg_body_focus), obj);
723 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
724 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
725 "changed", G_CALLBACK (recpt_field_changed), obj);
726 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
727 "changed", G_CALLBACK (recpt_field_changed), obj);
728 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
729 "changed", G_CALLBACK (recpt_field_changed), obj);
730 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
731 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
732 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
734 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
735 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
737 g_signal_connect (G_OBJECT (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll))),
739 G_CALLBACK (vadj_changed),
742 priv->clipboard_change_handler_id =
743 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
744 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
745 priv->default_clipboard_change_handler_id =
746 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
747 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
749 g_signal_connect (G_OBJECT (priv->msg_body), "cut-clipboard", G_CALLBACK (cut_clipboard_check), NULL);
750 g_signal_connect (G_OBJECT (priv->msg_body), "copy-clipboard", G_CALLBACK (copy_clipboard_check), NULL);
755 init_window (ModestMsgEditWindow *obj)
757 GtkWidget *from_caption, *to_caption, *subject_caption;
758 GtkWidget *main_vbox;
759 ModestMsgEditWindowPrivate *priv;
760 GtkActionGroup *action_group;
761 ModestWindowPrivate *parent_priv;
762 GdkPixbuf *window_icon = NULL;
763 GError *error = NULL;
765 GtkSizeGroup *size_group;
766 GtkWidget *subject_box;
767 GtkWidget *attachment_icon;
768 GtkWidget *window_box;
769 #if (GTK_MINOR_VERSION >= 10)
770 GdkAtom deserialize_type;
772 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
773 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
775 parent_priv->ui_manager = gtk_ui_manager_new();
776 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
777 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
779 /* Add common actions */
780 gtk_action_group_add_actions (action_group,
781 modest_msg_edit_action_entries,
782 G_N_ELEMENTS (modest_msg_edit_action_entries),
784 gtk_action_group_add_toggle_actions (action_group,
785 modest_msg_edit_toggle_action_entries,
786 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
788 gtk_action_group_add_radio_actions (action_group,
789 modest_msg_edit_alignment_radio_action_entries,
790 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
792 G_CALLBACK (modest_ui_actions_on_change_justify),
794 gtk_action_group_add_radio_actions (action_group,
795 modest_msg_edit_priority_action_entries,
796 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
798 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
800 gtk_action_group_add_radio_actions (action_group,
801 modest_msg_edit_file_format_action_entries,
802 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
803 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
804 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
806 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
807 g_object_unref (action_group);
809 /* Load the UI definition */
810 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
813 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
814 g_clear_error (&error);
817 /* Add accelerators */
818 gtk_window_add_accel_group (GTK_WINDOW (obj),
819 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
821 parent_priv->menubar = NULL;
823 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
825 /* Note: This ModestPairList* must exist for as long as the combo
826 * that uses it, because the ModestComboBox uses the ID opaquely,
827 * so it can't know how to manage its memory. */
828 priv->from_field = modest_combo_box_new (NULL, g_str_equal);
830 priv->to_field = modest_recpt_editor_new ();
831 priv->cc_field = modest_recpt_editor_new ();
832 priv->bcc_field = modest_recpt_editor_new ();
833 subject_box = gtk_hbox_new (FALSE, 0);
834 priv->priority_icon = gtk_image_new ();
835 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
836 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
837 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
838 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
839 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
840 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
841 priv->add_attachment_button = gtk_button_new ();
842 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
843 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
844 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
845 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
846 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
847 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
848 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
849 priv->attachments_view = modest_attachments_view_new (NULL);
851 priv->header_box = gtk_vbox_new (FALSE, 0);
853 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
854 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
855 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
856 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
857 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
858 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
859 g_object_unref (size_group);
861 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
862 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
863 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
864 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
865 gtk_size_group_add_widget (size_group, priv->subject_field);
866 gtk_size_group_add_widget (size_group, priv->attachments_view);
867 g_object_unref (size_group);
869 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
870 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
871 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
872 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
873 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
874 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
875 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
878 priv->msg_body = wp_text_view_new ();
879 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
880 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
881 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
882 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
883 #if (GTK_MINOR_VERSION >= 10)
884 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
885 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
887 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
888 deserialize_type, TRUE);
890 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
892 priv->find_toolbar = hildon_find_toolbar_new (NULL);
893 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
895 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
897 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
898 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
899 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
900 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->scroll), TRUE);
902 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
904 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
905 priv->frame = gtk_frame_new (NULL);
906 gtk_box_pack_start (GTK_BOX(main_vbox), priv->frame, TRUE, TRUE, 0);
908 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
909 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
910 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
912 window_box = gtk_vbox_new (FALSE, 0);
913 gtk_container_add (GTK_CONTAINER(obj), window_box);
915 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
917 gtk_container_add (GTK_CONTAINER (priv->frame), priv->msg_body);
919 /* Set window icon */
920 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
922 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
923 g_object_unref (window_icon);
928 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
930 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
932 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
933 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
934 priv->clipboard_change_handler_id))
935 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
936 priv->clipboard_change_handler_id);
937 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
938 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
939 priv->default_clipboard_change_handler_id))
940 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
941 priv->default_clipboard_change_handler_id);
943 if (priv->account_removed_handler_id &&
944 g_signal_handler_is_connected (modest_runtime_get_account_store (),
945 priv->account_removed_handler_id))
946 g_signal_handler_disconnect(modest_runtime_get_account_store (),
947 priv->account_removed_handler_id);
951 modest_msg_edit_window_finalize (GObject *obj)
953 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
955 /* Sanity check: shouldn't be needed, the window mgr should
956 call this function before */
957 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
959 if (priv->clipboard_text != NULL) {
960 g_free (priv->clipboard_text);
961 priv->clipboard_text = NULL;
964 if (priv->draft_msg != NULL) {
965 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
966 if (TNY_IS_HEADER (header)) {
967 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
968 modest_window_mgr_unregister_header (mgr, header);
970 g_object_unref (priv->draft_msg);
971 priv->draft_msg = NULL;
973 if (priv->outbox_msg != NULL) {
974 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
975 if (TNY_IS_HEADER (header)) {
976 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
977 modest_window_mgr_unregister_header (mgr, header);
979 g_object_unref (priv->outbox_msg);
980 priv->outbox_msg = NULL;
982 if (priv->scroll_drag_timeout_id > 0) {
983 g_source_remove (priv->scroll_drag_timeout_id);
984 priv->scroll_drag_timeout_id = 0;
986 g_free (priv->msg_uid);
987 g_free (priv->last_search);
988 g_slist_free (priv->font_items_group);
989 g_slist_free (priv->size_items_group);
990 g_object_unref (priv->attachments);
991 g_object_unref (priv->images);
993 /* This had to stay alive for as long as the combobox that used it: */
994 modest_pair_list_free (priv->from_field_protos);
996 G_OBJECT_CLASS(parent_class)->finalize (obj);
1000 pixbuf_from_stream (TnyStream *stream, const gchar *mime_type, guint64 *stream_size)
1002 GdkPixbufLoader *loader;
1008 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1010 if (loader == NULL) {
1016 tny_stream_reset (TNY_STREAM (stream));
1017 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1018 GError *error = NULL;
1019 unsigned char read_buffer[128];
1021 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1023 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, &error)) {
1028 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1030 g_object_ref (pixbuf);
1031 gdk_pixbuf_loader_close (loader, NULL);
1032 g_object_unref (loader);
1037 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1038 GdkPixbuf *new_pixbuf;
1040 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1041 gdk_pixbuf_get_width (pixbuf);
1042 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1043 g_object_unref (pixbuf);
1044 pixbuf = new_pixbuf;
1048 *stream_size = size;
1054 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1056 ModestMsgEditWindowPrivate *priv;
1059 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1061 for (iter = tny_list_create_iterator (attachments);
1062 !tny_iterator_is_done (iter);
1063 tny_iterator_next (iter)) {
1064 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1065 const gchar *cid = tny_mime_part_get_content_id (part);
1066 const gchar *mime_type = tny_mime_part_get_content_type (part);
1067 if ((cid != NULL)&&(mime_type != NULL)) {
1068 guint64 stream_size;
1069 TnyStream *stream = tny_mime_part_get_decoded_stream (part);
1070 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
1073 g_object_unref (stream);
1075 if (pixbuf != NULL) {
1076 priv->images_count ++;
1077 priv->images_size += stream_size;
1078 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1079 g_object_unref (pixbuf);
1082 g_object_unref (part);
1084 g_object_unref (iter);
1088 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1090 TnyMimePart *parent = NULL;
1091 const gchar *content_type = NULL;
1092 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1094 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1096 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1097 parent = g_object_ref (msg);
1098 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1099 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1102 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1103 iter = tny_list_create_iterator (parts);
1104 while (!tny_iterator_is_done (iter)) {
1106 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1107 content_type = tny_mime_part_get_content_type (part);
1108 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1112 g_object_unref (part);
1114 tny_iterator_next (iter);
1116 g_object_unref (iter);
1117 g_object_unref (parts);
1120 if (parent != NULL) {
1121 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1124 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1125 iter = tny_list_create_iterator (parts);
1126 while (!tny_iterator_is_done (iter)) {
1128 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1129 content_type = tny_mime_part_get_content_type (part);
1130 if (content_type && g_str_has_prefix (content_type, "image/")) {
1131 tny_list_prepend (priv->images, (GObject *) part);
1133 g_object_unref (part);
1134 tny_iterator_next (iter);
1136 g_object_unref (iter);
1137 g_object_unref (parts);
1138 g_object_unref (parent);
1143 update_last_cid (ModestMsgEditWindow *self, TnyList *attachments)
1146 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1148 for (iter = tny_list_create_iterator (attachments) ;
1149 !tny_iterator_is_done (iter);
1150 tny_iterator_next (iter)) {
1151 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1152 const gchar *cid = tny_mime_part_get_content_id (part);
1154 char *invalid = NULL;
1155 gint int_cid = strtol (cid, &invalid, 10);
1156 if ((invalid != NULL) && (*invalid == '\0') && (int_cid > priv->last_cid)) {
1157 priv->last_cid = int_cid;
1160 g_object_unref (part);
1162 g_object_unref (iter);
1166 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1169 const gchar *to, *cc, *bcc, *subject;
1171 ModestMsgEditWindowPrivate *priv;
1173 TnyHeaderFlags priority_flags;
1174 TnyFolder *msg_folder;
1175 gboolean is_html = FALSE;
1177 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1178 g_return_if_fail (TNY_IS_MSG (msg));
1180 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1182 header = tny_msg_get_header (msg);
1183 to = tny_header_get_to (header);
1184 cc = tny_header_get_cc (header);
1185 bcc = tny_header_get_bcc (header);
1186 subject = tny_header_get_subject (header);
1187 priority_flags = tny_header_get_priority (header);
1190 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1192 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1193 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1194 gtk_widget_show (priv->cc_caption);
1195 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1196 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1197 gtk_widget_hide (priv->cc_caption);
1200 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1201 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1202 gtk_widget_show (priv->bcc_caption);
1203 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1204 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1205 gtk_widget_hide (priv->bcc_caption);
1208 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1209 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1212 update_window_title (self);
1214 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1215 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1217 if ((body == NULL)||(body[0] == '\0')) {
1219 body = modest_text_utils_convert_to_html ("");
1222 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1223 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1226 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1229 /* Add attachments to the view */
1230 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1231 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1232 if (tny_list_get_length (priv->attachments) == 0) {
1233 gtk_widget_hide (priv->attachments_caption);
1235 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1236 gtk_widget_show_all (priv->attachments_caption);
1238 get_related_images (self, msg);
1239 update_last_cid (self, priv->attachments);
1240 update_last_cid (self, priv->images);
1241 replace_with_images (self, priv->images);
1243 if (preserve_is_rich && !is_html) {
1244 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1245 /* Get the default format required from configuration */
1246 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1247 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1250 /* Set the default focus depending on having already a To: field or not */
1251 if ((!to)||(*to == '\0')) {
1252 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1254 gtk_widget_grab_focus (priv->msg_body);
1257 /* TODO: lower priority, select in the From: combo to the
1258 value that comes from msg <- not sure, should it be
1261 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1263 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1264 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1266 modest_msg_edit_window_set_modified (self, FALSE);
1268 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1269 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1270 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1271 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1273 if (priv->msg_uid) {
1274 g_free (priv->msg_uid);
1275 priv->msg_uid = NULL;
1278 /* we should set a reference to the incoming message if it is a draft */
1279 msg_folder = tny_msg_get_folder (msg);
1281 if (modest_tny_folder_is_local_folder (msg_folder)) {
1282 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1283 if (type == TNY_FOLDER_TYPE_INVALID)
1284 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1286 if (type == TNY_FOLDER_TYPE_DRAFTS)
1287 priv->draft_msg = g_object_ref(msg);
1288 if (type == TNY_FOLDER_TYPE_OUTBOX)
1289 priv->outbox_msg = g_object_ref(msg);
1290 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1292 g_object_unref (msg_folder);
1297 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
1300 GList *item_children, *node;
1301 GtkWidget *bin_child;
1303 bin_child = gtk_bin_get_child (GTK_BIN(item));
1305 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
1307 for (node = item_children; node != NULL; node = g_list_next (node)) {
1308 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
1309 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
1312 g_list_free (item_children);
1316 menu_tool_button_dont_expand (GtkMenuToolButton *item)
1319 GList *item_children, *node;
1321 box = gtk_bin_get_child (GTK_BIN (item));
1322 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
1323 item_children = gtk_container_get_children (GTK_CONTAINER (box));
1325 for (node = item_children; node != NULL; node = g_list_next (node)) {
1326 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
1327 if (GTK_IS_TOGGLE_BUTTON (node->data))
1328 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
1329 else if (GTK_IS_BUTTON (node->data))
1330 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
1332 g_list_free (item_children);
1337 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1339 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1340 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1341 GtkWidget *placeholder;
1342 GtkWidget *tool_item;
1347 GtkWidget *sizes_menu;
1348 GtkWidget *fonts_menu;
1349 GSList *radio_group = NULL;
1350 GSList *node = NULL;
1354 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1355 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1357 /* Font color placeholder */
1358 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1359 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1362 tool_item = GTK_WIDGET (gtk_tool_item_new ());
1363 priv->font_color_button = hildon_color_button_new ();
1364 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
1365 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1366 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
1367 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1368 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1369 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1370 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1372 G_CALLBACK (modest_msg_edit_window_color_button_change),
1375 /* Font size and face placeholder */
1376 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1377 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1379 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1380 priv->size_tool_button_label = gtk_label_new (NULL);
1381 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1382 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1383 size_text,"</span>", NULL);
1384 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1386 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
1387 sizes_menu = gtk_menu_new ();
1388 priv->size_items_group = NULL;
1390 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1391 GtkWidget *size_menu_item;
1393 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1394 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
1395 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
1396 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
1397 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
1398 gtk_widget_show (size_menu_item);
1400 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
1404 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1405 GtkWidget *item = (GtkWidget *) node->data;
1406 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
1410 priv->size_items_group = g_slist_reverse (priv->size_items_group);
1411 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
1412 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1413 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1414 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1415 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1416 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1417 priv->font_size_toolitem = tool_item;
1420 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1421 priv->font_tool_button_label = gtk_label_new (NULL);
1422 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1423 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1425 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
1426 fonts_menu = gtk_menu_new ();
1427 priv->font_items_group = NULL;
1429 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1430 GtkWidget *font_menu_item;
1431 GtkWidget *child_label;
1433 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
1434 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
1435 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
1436 wp_get_font_name (font_index), "</span>", NULL);
1437 gtk_label_set_markup (GTK_LABEL (child_label), markup);
1440 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
1441 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
1442 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
1443 gtk_widget_show (font_menu_item);
1445 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
1448 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1449 GtkWidget *item = (GtkWidget *) node->data;
1450 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
1453 priv->font_items_group = g_slist_reverse (priv->font_items_group);
1454 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
1455 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1456 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1457 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1458 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1459 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1460 priv->font_face_toolitem = tool_item;
1462 /* Set expand and homogeneous for remaining items */
1463 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1464 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1465 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1466 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1467 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1468 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1469 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1470 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1471 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1473 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1474 will not show the tool items added to the placeholders) */
1475 gtk_widget_show_all (parent_priv->toolbar);
1477 /* Set the no show all *after* showing all items. We do not
1478 want the toolbar to be shown with a show all because it
1479 could go agains the gconf setting regarding showing or not
1480 the toolbar of the editor window */
1481 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1487 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean preserve_is_rich)
1490 ModestWindowPrivate *parent_priv;
1491 ModestMsgEditWindowPrivate *priv;
1492 ModestPair *account_pair = NULL;
1493 ModestDimmingRulesGroup *menu_rules_group = NULL;
1494 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1495 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1496 ModestWindowMgr *mgr = NULL;
1498 g_return_val_if_fail (msg, NULL);
1499 g_return_val_if_fail (account_name, NULL);
1501 mgr = modest_runtime_get_window_mgr ();
1503 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1505 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1506 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1508 /* Menubar. Update the state of some toggles */
1509 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1510 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
1511 priv->from_field_protos = get_transports ();
1512 modest_combo_box_set_pair_list (MODEST_COMBO_BOX (priv->from_field), priv->from_field_protos);
1513 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1514 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1517 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1519 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1521 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1523 account_pair = find_transport_from_message_sender (priv->from_field_protos, msg);
1524 if (account_pair == NULL) {
1525 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
1527 if (account_pair != NULL)
1528 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
1530 priv->original_account_name = account_pair ? (const gchar *) account_pair->first : NULL;
1532 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new ();
1533 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1534 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1535 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1536 /* Add common dimming rules */
1537 modest_dimming_rules_group_add_rules (menu_rules_group,
1538 modest_msg_edit_window_menu_dimming_entries,
1539 G_N_ELEMENTS (modest_msg_edit_window_menu_dimming_entries),
1540 MODEST_WINDOW (obj));
1541 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1542 modest_msg_edit_window_toolbar_dimming_entries,
1543 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1544 MODEST_WINDOW (obj));
1545 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_button,
1546 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1547 MODEST_WINDOW (obj));
1548 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1549 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1550 MODEST_WINDOW (obj));
1551 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1552 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1553 MODEST_WINDOW (obj));
1554 modest_dimming_rules_group_add_rules (clipboard_rules_group,
1555 modest_msg_edit_window_clipboard_dimming_entries,
1556 G_N_ELEMENTS (modest_msg_edit_window_clipboard_dimming_entries),
1557 MODEST_WINDOW (obj));
1558 /* Insert dimming rules group for this window */
1559 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1560 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1561 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1562 /* Checks the dimming rules */
1563 g_object_unref (menu_rules_group);
1564 g_object_unref (toolbar_rules_group);
1565 g_object_unref (clipboard_rules_group);
1566 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, MODEST_MSG_EDIT_WINDOW (obj));
1568 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1570 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1572 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1573 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1574 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1575 priv->update_caption_visibility = TRUE;
1577 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1579 /* Track account-removed signal, this window should be closed
1580 in the case we're creating a mail associated to the account
1582 priv->account_removed_handler_id =
1583 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1585 G_CALLBACK(on_account_removed),
1588 return (ModestWindow*) obj;
1592 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1594 GString **string_buffer = (GString **) user_data;
1596 *string_buffer = g_string_append (*string_buffer, buffer);
1602 * @result: A new string which should be freed with g_free().
1605 get_formatted_data (ModestMsgEditWindow *edit_window)
1607 ModestMsgEditWindowPrivate *priv;
1608 GString *string_buffer = g_string_new ("");
1610 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1612 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1614 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1616 return g_string_free (string_buffer, FALSE);
1621 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1624 const gchar *account_name;
1625 ModestMsgEditWindowPrivate *priv;
1626 TnyIterator *att_iter;
1628 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1630 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1632 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1633 g_return_val_if_fail (account_name, NULL);
1636 /* don't free these (except from) */
1637 data = g_slice_new0 (MsgData);
1638 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1640 data->account_name = g_strdup (account_name);
1641 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1642 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1643 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1644 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1645 if (priv->draft_msg) {
1646 data->draft_msg = g_object_ref (priv->draft_msg);
1647 } else if (priv->outbox_msg) {
1648 data->draft_msg = g_object_ref (priv->outbox_msg);
1650 data->draft_msg = NULL;
1653 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1655 gtk_text_buffer_get_bounds (buf, &b, &e);
1656 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1658 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1659 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1661 data->html_body = NULL;
1663 /* deep-copy the data */
1664 att_iter = tny_list_create_iterator (priv->attachments);
1665 data->attachments = NULL;
1666 while (!tny_iterator_is_done (att_iter)) {
1667 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1668 if (!(TNY_IS_MIME_PART(part))) {
1669 g_warning ("strange data in attachment list");
1670 g_object_unref (part);
1671 tny_iterator_next (att_iter);
1674 data->attachments = g_list_append (data->attachments,
1676 tny_iterator_next (att_iter);
1678 g_object_unref (att_iter);
1680 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1681 att_iter = tny_list_create_iterator (priv->images);
1682 data->images = NULL;
1683 while (!tny_iterator_is_done (att_iter)) {
1684 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1686 if (!(TNY_IS_MIME_PART(part))) {
1687 g_warning ("strange data in attachment list");
1688 g_object_unref (part);
1689 tny_iterator_next (att_iter);
1692 cid = tny_mime_part_get_content_id (part);
1694 gchar *image_tag_id;
1695 GtkTextTag *image_tag;
1697 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1698 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1699 g_free (image_tag_id);
1701 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1703 ((gtk_text_iter_has_tag (&iter, image_tag))||
1704 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1705 data->images = g_list_append (data->images,
1706 g_object_ref (part));
1708 g_object_unref (part);
1709 tny_iterator_next (att_iter);
1711 g_object_unref (att_iter);
1713 data->priority_flags = priv->priority_flags;
1720 unref_gobject (GObject *obj, gpointer data)
1722 if (!G_IS_OBJECT(obj))
1724 g_object_unref (obj);
1728 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1731 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1739 g_free (data->from);
1740 g_free (data->subject);
1741 g_free (data->plain_body);
1742 g_free (data->html_body);
1743 g_free (data->account_name);
1745 if (data->draft_msg != NULL) {
1746 g_object_unref (data->draft_msg);
1747 data->draft_msg = NULL;
1750 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1751 g_list_free (data->attachments);
1752 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1753 g_list_free (data->images);
1755 g_slice_free (MsgData, data);
1759 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1761 guint64 *parts_size)
1763 ModestMsgEditWindowPrivate *priv;
1765 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1767 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1769 /* TODO: add images */
1770 *parts_size += priv->images_size;
1771 *parts_count += priv->images_count;
1776 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1779 ModestMsgEditWindowPrivate *priv = NULL;
1780 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1782 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1784 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1786 return MODEST_MSG_EDIT_FORMAT_HTML;
1788 return MODEST_MSG_EDIT_FORMAT_TEXT;
1792 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1793 ModestMsgEditFormat format)
1795 ModestMsgEditWindowPrivate *priv;
1797 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1798 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1801 case MODEST_MSG_EDIT_FORMAT_HTML:
1802 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1804 case MODEST_MSG_EDIT_FORMAT_TEXT:
1805 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1808 g_return_if_reached ();
1812 ModestMsgEditFormatState *
1813 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1815 ModestMsgEditFormatState *format_state = NULL;
1816 ModestMsgEditWindowPrivate *priv;
1817 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1819 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1820 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1822 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1824 format_state = g_new0 (ModestMsgEditFormatState, 1);
1825 format_state->bold = buffer_format->bold&0x1;
1826 format_state->italics = buffer_format->italic&0x1;
1827 format_state->bullet = buffer_format->bullet&0x1;
1828 format_state->color = buffer_format->color;
1829 format_state->font_size = buffer_format->font_size;
1830 format_state->font_family = wp_get_font_name (buffer_format->font);
1831 format_state->justification = buffer_format->justification;
1832 g_free (buffer_format);
1834 return format_state;
1839 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1840 const ModestMsgEditFormatState *format_state)
1842 ModestMsgEditWindowPrivate *priv;
1843 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1844 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1845 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1846 g_return_if_fail (format_state != NULL);
1848 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1849 gtk_widget_grab_focus (priv->msg_body);
1850 buffer_format->bold = (format_state->bold != FALSE);
1851 buffer_format->italic = (format_state->italics != FALSE);
1852 buffer_format->color = format_state->color;
1853 buffer_format->font_size = format_state->font_size;
1854 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1855 buffer_format->justification = format_state->justification;
1856 buffer_format->bullet = format_state->bullet;
1858 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1860 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1861 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1862 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1863 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1864 buffer_format->cs.font = (buffer_format->font != current_format->font);
1865 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1866 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1868 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1869 if (buffer_format->cs.bold) {
1870 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1871 GINT_TO_POINTER (buffer_format->bold&0x1));
1873 if (buffer_format->cs.italic) {
1874 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1875 GINT_TO_POINTER (buffer_format->italic&0x1));
1877 if (buffer_format->cs.color) {
1878 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1879 GINT_TO_POINTER (&(buffer_format->color)));
1881 if (buffer_format->cs.font_size) {
1882 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1883 GINT_TO_POINTER (buffer_format->font_size));
1885 if (buffer_format->cs.justification) {
1886 switch (buffer_format->justification) {
1887 case GTK_JUSTIFY_LEFT:
1888 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1889 GINT_TO_POINTER(TRUE));
1891 case GTK_JUSTIFY_CENTER:
1892 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1893 GINT_TO_POINTER(TRUE));
1895 case GTK_JUSTIFY_RIGHT:
1896 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1897 GINT_TO_POINTER(TRUE));
1904 if (buffer_format->cs.font) {
1905 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1906 GINT_TO_POINTER (buffer_format->font));
1908 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1909 if (buffer_format->cs.bullet) {
1910 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
1911 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
1913 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1915 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
1917 g_free (current_format);
1922 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1924 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1926 ModestWindowPrivate *parent_priv;
1927 ModestMsgEditWindowPrivate *priv;
1928 GtkWidget *new_size_menuitem;
1929 GtkWidget *new_font_menuitem;
1931 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1932 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1934 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1935 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1936 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1937 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1939 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1940 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1941 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1944 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1946 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1947 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1949 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1950 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1952 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
1953 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
1956 switch (buffer_format->justification)
1958 case GTK_JUSTIFY_LEFT:
1959 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1961 case GTK_JUSTIFY_CENTER:
1962 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1964 case GTK_JUSTIFY_RIGHT:
1965 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1972 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1974 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1975 G_CALLBACK (modest_msg_edit_window_color_button_change),
1977 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1978 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1979 G_CALLBACK (modest_msg_edit_window_color_button_change),
1982 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1983 buffer_format->font_size))->data);
1984 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1988 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1989 markup = g_strconcat ("<span font_family='Sans'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1990 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1992 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1993 G_CALLBACK (modest_msg_edit_window_size_change),
1995 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1996 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1997 G_CALLBACK (modest_msg_edit_window_size_change),
2001 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
2002 buffer_format->font))->data);
2003 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
2007 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
2008 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2009 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2011 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
2012 G_CALLBACK (modest_msg_edit_window_font_change),
2014 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
2015 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
2016 G_CALLBACK (modest_msg_edit_window_font_change),
2020 g_free (buffer_format);
2024 #ifdef MODEST_HILDON_VERSION_0
2026 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2029 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2030 ModestMsgEditWindowPrivate *priv;
2031 GtkWidget *dialog = NULL;
2033 GdkColor *new_color = NULL;
2035 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2036 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2038 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2039 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2040 g_free (buffer_format);
2042 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2043 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2044 if (new_color != NULL) {
2045 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2046 (gpointer) new_color);
2049 gtk_widget_destroy (dialog);
2054 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2057 ModestMsgEditWindowPrivate *priv;
2058 GtkWidget *dialog = NULL;
2060 GdkColor *old_color = NULL;
2061 const GdkColor *new_color = NULL;
2063 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2064 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2066 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2067 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2069 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2070 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2071 if (new_color != NULL)
2072 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2074 gtk_widget_destroy (dialog);
2080 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2083 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2084 ModestMsgEditWindowPrivate *priv;
2085 GtkWidget *dialog = NULL;
2087 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2088 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2090 dialog = hildon_color_chooser_new ();
2091 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2092 g_free (buffer_format);
2094 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2096 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2097 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2100 gtk_widget_destroy (dialog);
2105 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2108 ModestMsgEditWindowPrivate *priv;
2109 GtkWidget *dialog = NULL;
2110 GdkColor *old_color = NULL;
2112 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2113 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2115 dialog = hildon_color_chooser_new ();
2116 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2118 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2120 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2121 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2123 gtk_widget_destroy (dialog);
2126 #endif /*!MODEST_HILDON_VERSION_0*/
2130 static TnyStream* create_stream_for_uri (const gchar* uri)
2135 TnyStream *result = NULL;
2137 GnomeVFSHandle *handle = NULL;
2138 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2139 if (test == GNOME_VFS_OK) {
2140 /* Create the tinymail stream: */
2141 /* Presumably tinymai will call gnome_vfs_close (handle) later. */
2142 result = TNY_STREAM (tny_vfs_stream_new (handle));
2149 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2152 ModestMsgEditWindowPrivate *priv;
2153 GtkWidget *dialog = NULL;
2155 GSList *uris = NULL;
2156 GSList *uri_node = NULL;
2158 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2160 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2161 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2162 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2164 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2166 response = gtk_dialog_run (GTK_DIALOG (dialog));
2168 case GTK_RESPONSE_OK:
2169 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2174 gtk_widget_destroy (dialog);
2176 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2178 GnomeVFSHandle *handle = NULL;
2179 GnomeVFSResult result;
2180 GtkTextIter position;
2181 GtkTextMark *insert_mark;
2183 uri = (const gchar *) uri_node->data;
2184 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2185 if (result == GNOME_VFS_OK) {
2187 GnomeVFSFileInfo *info;
2188 gchar *filename, *basename, *escaped_filename;
2189 TnyMimePart *mime_part;
2191 const gchar *mime_type = NULL;
2192 GnomeVFSURI *vfs_uri;
2193 guint64 stream_size;
2195 vfs_uri = gnome_vfs_uri_new (uri);
2197 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2198 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2199 g_free (escaped_filename);
2200 gnome_vfs_uri_unref (vfs_uri);
2201 info = gnome_vfs_file_info_new ();
2203 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2204 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2206 mime_type = gnome_vfs_file_info_get_mime_type (info);
2208 mime_part = tny_platform_factory_new_mime_part
2209 (modest_runtime_get_platform_factory ());
2211 TnyStream *stream = create_stream_for_uri (uri);
2212 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2214 content_id = g_strdup_printf ("%d", priv->last_cid);
2215 tny_mime_part_set_content_id (mime_part, content_id);
2216 g_free (content_id);
2219 basename = g_path_get_basename (filename);
2220 tny_mime_part_set_filename (mime_part, basename);
2223 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
2225 if (pixbuf != NULL) {
2226 priv->images_size += stream_size;
2227 priv->images_count ++;
2228 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2229 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2230 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
2233 tny_list_prepend (priv->images, (GObject *) mime_part);
2234 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2236 g_object_unref (mime_part);
2237 gnome_vfs_file_info_unref (info);
2246 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2248 GtkWidget *dialog = NULL;
2250 GSList *uris = NULL;
2253 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2254 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2255 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2257 response = gtk_dialog_run (GTK_DIALOG (dialog));
2259 case GTK_RESPONSE_OK:
2260 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2265 gtk_widget_destroy (dialog);
2267 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2268 const gchar *uri = (const gchar *) uri_node->data;
2269 modest_msg_edit_window_attach_file_one (window, uri);
2271 g_slist_foreach (uris, (GFunc) g_free, NULL);
2272 g_slist_free (uris);
2276 modest_msg_edit_window_attach_file_one (
2277 ModestMsgEditWindow *window,
2280 GnomeVFSHandle *handle = NULL;
2281 ModestMsgEditWindowPrivate *priv;
2282 GnomeVFSResult result;
2284 g_return_if_fail (window);
2285 g_return_if_fail (uri);
2287 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2289 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2290 if (result == GNOME_VFS_OK) {
2291 TnyMimePart *mime_part;
2293 const gchar *mime_type = NULL;
2295 gchar *escaped_filename;
2298 GnomeVFSFileInfo *info;
2299 GnomeVFSURI *vfs_uri;
2301 vfs_uri = gnome_vfs_uri_new (uri);
2304 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2305 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2306 g_free (escaped_filename);
2307 gnome_vfs_uri_unref (vfs_uri);
2309 info = gnome_vfs_file_info_new ();
2311 if (gnome_vfs_get_file_info (uri,
2313 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2315 mime_type = gnome_vfs_file_info_get_mime_type (info);
2316 mime_part = tny_platform_factory_new_mime_part
2317 (modest_runtime_get_platform_factory ());
2318 stream = TNY_STREAM (tny_vfs_stream_new (handle));
2320 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2322 g_object_unref (stream);
2324 content_id = g_strdup_printf ("%d", priv->last_cid);
2325 tny_mime_part_set_content_id (mime_part, content_id);
2326 g_free (content_id);
2329 basename = g_path_get_basename (filename);
2330 tny_mime_part_set_filename (mime_part, basename);
2333 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2334 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2336 info->size == 0, info->size);
2337 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2338 gtk_widget_show_all (priv->attachments_caption);
2339 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2341 g_object_unref (mime_part);
2342 gnome_vfs_file_info_unref (info);
2347 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2350 ModestMsgEditWindowPrivate *priv;
2353 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2354 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2356 if (att_list == NULL) {
2357 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2359 g_object_ref (att_list);
2362 if (tny_list_get_length (att_list) == 0) {
2363 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2365 GtkWidget *confirmation_dialog = NULL;
2366 gboolean dialog_response;
2367 gchar *message = NULL;
2368 gchar *filename = NULL;
2370 if (tny_list_get_length (att_list) == 1) {
2372 iter = tny_list_create_iterator (att_list);
2373 part = (TnyMimePart *) tny_iterator_get_current (iter);
2374 g_object_unref (iter);
2375 if (TNY_IS_MSG (part)) {
2376 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2378 filename = g_strdup (tny_header_get_subject (header));
2379 g_object_unref (header);
2381 if (filename == NULL) {
2382 filename = g_strdup (_("mail_va_no_subject"));
2385 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2387 g_object_unref (part);
2389 filename = g_strdup ("");
2391 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
2392 (tny_list_get_length (att_list) == 1)), filename);
2394 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
2396 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
2397 gtk_widget_destroy (confirmation_dialog);
2398 if (!dialog_response) {
2399 g_object_unref (att_list);
2402 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
2404 for (iter = tny_list_create_iterator (att_list);
2405 !tny_iterator_is_done (iter);
2406 tny_iterator_next (iter)) {
2407 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2408 const gchar *att_id;
2409 tny_list_remove (priv->attachments, (GObject *) mime_part);
2411 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2413 if (tny_list_get_length (priv->attachments) == 0)
2414 gtk_widget_hide (priv->attachments_caption);
2415 att_id = tny_mime_part_get_content_id (mime_part);
2417 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2419 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2420 g_object_unref (mime_part);
2422 g_object_unref (iter);
2425 g_object_unref (att_list);
2427 /* if the last attachment has been removed, focus the Subject: field */
2428 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2429 gtk_widget_grab_focus (priv->subject_field);
2433 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2436 ModestMsgEditWindowPrivate *priv;
2437 GdkColor *new_color;
2438 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2440 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2441 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2444 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2446 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2448 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2450 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2455 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
2458 ModestMsgEditWindowPrivate *priv;
2459 gint new_size_index;
2460 ModestMsgEditWindow *window;
2463 window = MODEST_MSG_EDIT_WINDOW (userdata);
2464 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2465 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2467 if (gtk_check_menu_item_get_active (menu_item)) {
2469 WPTextBufferFormat format;
2471 memset (&format, 0, sizeof (format));
2472 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2474 label = gtk_bin_get_child (GTK_BIN (menu_item));
2476 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
2477 format.cs.font_size = TRUE;
2478 format.cs.text_position = TRUE;
2479 format.cs.font = TRUE;
2480 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
2481 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2483 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2484 GINT_TO_POINTER (wp_get_font_size_index (new_size_index, 12))))
2485 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2487 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2488 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
2489 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2495 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
2498 ModestMsgEditWindowPrivate *priv;
2499 gint new_font_index;
2500 ModestMsgEditWindow *window;
2503 window = MODEST_MSG_EDIT_WINDOW (userdata);
2504 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2505 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2507 if (gtk_check_menu_item_get_active (menu_item)) {
2510 label = gtk_bin_get_child (GTK_BIN (menu_item));
2512 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
2514 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2515 GINT_TO_POINTER(new_font_index)))
2516 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2518 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2519 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2520 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2526 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
2528 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
2529 ModestWindowPrivate *parent_priv;
2530 ModestWindowMgr *mgr;
2531 gboolean is_fullscreen;
2532 GtkAction *fs_toggle_action;
2535 mgr = modest_runtime_get_window_mgr ();
2536 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
2538 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
2540 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2541 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2542 if (is_fullscreen != active)
2543 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2551 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2554 ModestMsgEditWindowPrivate *priv = NULL;
2555 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2557 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2558 if (!priv->update_caption_visibility)
2561 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2563 gtk_widget_show (priv->cc_caption);
2565 gtk_widget_hide (priv->cc_caption);
2567 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2571 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2574 ModestMsgEditWindowPrivate *priv = NULL;
2575 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2577 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2578 if (!priv->update_caption_visibility)
2581 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2583 gtk_widget_show (priv->bcc_caption);
2585 gtk_widget_hide (priv->bcc_caption);
2587 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2591 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2592 ModestRecptEditor *editor)
2594 ModestMsgEditWindowPrivate *priv;
2596 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2597 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2598 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2600 if (editor == NULL) {
2601 GtkWidget *view_focus;
2602 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2604 /* This code should be kept in sync with ModestRecptEditor. The
2605 textview inside the recpt editor is the one that really gets the
2606 focus. As it's inside a scrolled window, and this one inside the
2607 hbox recpt editor inherits from, we'll need to go up in the
2608 hierarchy to know if the text view is part of the recpt editor
2609 or if it's a different text entry */
2611 if (gtk_widget_get_parent (view_focus)) {
2612 GtkWidget *first_parent;
2614 first_parent = gtk_widget_get_parent (view_focus);
2615 if (gtk_widget_get_parent (first_parent) &&
2616 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2617 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2622 editor = MODEST_RECPT_EDITOR (priv->to_field);
2626 modest_address_book_select_addresses (editor);
2631 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2633 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2635 modest_msg_edit_window_open_addressbook (window, NULL);
2639 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2640 gboolean show_toolbar)
2642 ModestWindowPrivate *parent_priv;
2643 const gchar *action_name;
2646 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2647 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2649 /* We can not just use the code of
2650 modest_msg_edit_window_setup_toolbar because it has a
2651 mixture of both initialization and creation code. */
2653 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2655 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2657 /* Update also the actions (to update the toggles in the
2658 menus), we have to do it manually because some other window
2659 of the same time could have changed it (remember that the
2660 toolbar fullscreen mode is shared by all the windows of the
2662 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
2663 action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarFullScreenMenu";
2665 action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarNormalScreenMenu";
2667 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
2668 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
2674 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2675 TnyHeaderFlags priority_flags)
2677 ModestMsgEditWindowPrivate *priv;
2678 ModestWindowPrivate *parent_priv;
2680 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2682 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2683 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2685 if (priv->priority_flags != priority_flags) {
2686 GtkAction *priority_action = NULL;
2688 priv->priority_flags = priority_flags;
2690 switch (priority_flags) {
2691 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2692 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2693 gtk_widget_show (priv->priority_icon);
2694 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2695 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2697 case TNY_HEADER_FLAG_LOW_PRIORITY:
2698 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2699 gtk_widget_show (priv->priority_icon);
2700 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2701 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2704 gtk_widget_hide (priv->priority_icon);
2705 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2706 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2709 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2710 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2715 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2718 ModestMsgEditWindowPrivate *priv;
2719 ModestWindowPrivate *parent_priv;
2720 gint current_format;
2722 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2724 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2725 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2727 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2728 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2730 if (current_format != file_format) {
2731 switch (file_format) {
2732 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2733 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2734 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
2736 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2740 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2741 response = gtk_dialog_run (GTK_DIALOG (dialog));
2742 gtk_widget_destroy (dialog);
2743 if (response == GTK_RESPONSE_OK) {
2744 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2746 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2747 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
2752 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2757 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2760 ModestMsgEditWindowPrivate *priv;
2761 WPTextBufferFormat oldfmt, fmt;
2762 gint old_position = 0;
2766 GdkColor *color = NULL;
2767 gboolean bold, bold_set, italic, italic_set;
2768 gboolean underline, underline_set;
2769 gboolean strikethrough, strikethrough_set;
2770 gboolean position_set;
2771 gboolean font_size_set, font_set, color_set;
2774 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2775 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2777 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2779 /* First we get the currently selected font information */
2780 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2782 switch (oldfmt.text_position) {
2783 case TEXT_POSITION_NORMAL:
2786 case TEXT_POSITION_SUPERSCRIPT:
2794 g_object_set (G_OBJECT (dialog),
2795 "bold", oldfmt.bold != FALSE,
2796 "bold-set", !oldfmt.cs.bold,
2797 "underline", oldfmt.underline != FALSE,
2798 "underline-set", !oldfmt.cs.underline,
2799 "italic", oldfmt.italic != FALSE,
2800 "italic-set", !oldfmt.cs.italic,
2801 "strikethrough", oldfmt.strikethrough != FALSE,
2802 "strikethrough-set", !oldfmt.cs.strikethrough,
2803 "color", &oldfmt.color,
2804 "color-set", !oldfmt.cs.color,
2805 "size", wp_font_size[oldfmt.font_size],
2806 "size-set", !oldfmt.cs.font_size,
2807 "position", old_position,
2808 "position-set", !oldfmt.cs.text_position,
2809 "family", wp_get_font_name (oldfmt.font),
2810 "family-set", !oldfmt.cs.font,
2813 gtk_widget_show_all (dialog);
2814 response = gtk_dialog_run (GTK_DIALOG (dialog));
2815 if (response == GTK_RESPONSE_OK) {
2817 g_object_get( dialog,
2819 "bold-set", &bold_set,
2820 "underline", &underline,
2821 "underline-set", &underline_set,
2823 "italic-set", &italic_set,
2824 "strikethrough", &strikethrough,
2825 "strikethrough-set", &strikethrough_set,
2827 "color-set", &color_set,
2829 "size-set", &font_size_set,
2830 "family", &font_name,
2831 "family-set", &font_set,
2832 "position", &position,
2833 "position-set", &position_set,
2838 if (response == GTK_RESPONSE_OK) {
2839 memset(&fmt, 0, sizeof(fmt));
2845 fmt.italic = italic;
2846 fmt.cs.italic = TRUE;
2848 if (underline_set) {
2849 fmt.underline = underline;
2850 fmt.cs.underline = TRUE;
2852 if (strikethrough_set) {
2853 fmt.strikethrough = strikethrough;
2854 fmt.cs.strikethrough = TRUE;
2859 ? TEXT_POSITION_NORMAL
2860 : ( ( position == 1 )
2861 ? TEXT_POSITION_SUPERSCRIPT
2862 : TEXT_POSITION_SUBSCRIPT );
2863 fmt.cs.text_position = TRUE;
2864 fmt.font_size = oldfmt.font_size;
2868 fmt.cs.color = TRUE;
2871 fmt.font = wp_get_font_index(font_name,
2876 if (font_size_set) {
2877 fmt.cs.font_size = TRUE;
2878 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
2880 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2881 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2883 gtk_widget_destroy (dialog);
2885 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2889 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2891 ModestMsgEditWindowPrivate *priv;
2893 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2894 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2896 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2898 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2899 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2904 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2906 ModestMsgEditWindowPrivate *priv;
2908 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2909 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2911 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2913 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2914 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2919 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2921 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2923 priv->can_undo = can_undo;
2927 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2929 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2931 priv->can_redo = can_redo;
2935 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
2937 ModestMsgEditWindowPrivate *priv;
2938 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2939 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2941 return priv->can_undo;
2945 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
2947 ModestMsgEditWindowPrivate *priv;
2948 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2949 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2951 return priv->can_redo;
2956 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2959 GtkTextIter match_start, match_end;
2961 if (image_id == NULL)
2964 gtk_text_buffer_get_start_iter (buffer, &iter);
2966 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2967 GSList *tags = gtk_text_iter_get_tags (&match_start);
2969 for (node = tags; node != NULL; node = g_slist_next (node)) {
2970 GtkTextTag *tag = (GtkTextTag *) node->data;
2971 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2972 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2973 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2975 offset = gtk_text_iter_get_offset (&match_start);
2976 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2977 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2981 gtk_text_iter_forward_char (&iter);
2986 message_is_empty (ModestMsgEditWindow *window)
2988 ModestMsgEditWindowPrivate *priv = NULL;
2990 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2991 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2993 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
2994 * so we can ignore markup.
2996 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
2999 count = gtk_text_buffer_get_char_count (buf);
3005 msg_body_focus (GtkWidget *focus,
3006 GdkEventFocus *event,
3010 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3011 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3012 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3017 recpt_field_changed (GtkTextBuffer *buffer,
3018 ModestMsgEditWindow *editor)
3020 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3021 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3025 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3027 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3028 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3032 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3035 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3036 GtkTextBuffer *buffer;
3038 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3039 gtk_text_buffer_set_modified (buffer, modified);
3040 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3041 gtk_text_buffer_set_modified (buffer, modified);
3042 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3043 gtk_text_buffer_set_modified (buffer, modified);
3044 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3048 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3050 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3051 const char *account_name;
3052 GtkTextBuffer *buffer;
3054 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3055 if (gtk_text_buffer_get_modified (buffer))
3057 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3058 if (gtk_text_buffer_get_modified (buffer))
3060 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3061 if (gtk_text_buffer_get_modified (buffer))
3063 if (gtk_text_buffer_get_modified (priv->text_buffer))
3065 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
3066 if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3077 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3079 ModestMsgEditWindowPrivate *priv = NULL;
3081 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3082 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3084 /* check if there's no recipient added */
3085 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3086 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3087 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3088 /* no recipient contents, then select contacts */
3089 modest_msg_edit_window_open_addressbook (window, NULL);
3093 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3094 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3097 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3098 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3101 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3102 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3106 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3107 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3108 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3115 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3116 ModestMsgEditWindow *window)
3118 modest_msg_edit_window_offer_attach_file (window);
3122 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3124 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3126 return priv->clipboard_text;
3130 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3132 ModestMsgEditWindow *window)
3134 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3135 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3137 if (!GTK_WIDGET_VISIBLE (window))
3140 text = gtk_clipboard_wait_for_text (selection_clipboard);
3142 if (priv->clipboard_text != NULL) {
3143 g_free (priv->clipboard_text);
3145 priv->clipboard_text = text;
3147 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3150 subject_field_move_cursor (GtkEntry *entry,
3151 GtkMovementStep step,
3156 if (!GTK_WIDGET_VISIBLE (window))
3159 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3163 update_window_title (ModestMsgEditWindow *window)
3165 ModestMsgEditWindowPrivate *priv = NULL;
3166 const gchar *subject;
3168 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3169 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3170 if (subject == NULL || subject[0] == '\0')
3171 subject = _("mail_va_new_email");
3173 gtk_window_set_title (GTK_WINDOW (window), subject);
3178 subject_field_changed (GtkEditable *editable,
3179 ModestMsgEditWindow *window)
3181 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3182 update_window_title (window);
3183 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3184 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3185 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3189 subject_field_insert_text (GtkEditable *editable,
3191 gint new_text_length,
3193 ModestMsgEditWindow *window)
3195 GString *result = g_string_new ("");
3197 gint result_len = 0;
3198 const gchar *entry_text = NULL;
3201 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3202 old_length = g_utf8_strlen (entry_text, -1);
3204 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3205 gunichar c = g_utf8_get_char_validated (current, 8);
3206 /* Invalid unichar, stop */
3212 result = g_string_append_unichar (result, c);
3216 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3217 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3220 /* Prevent endless recursion */
3221 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3222 g_signal_emit_by_name (editable, "insert-text",
3223 (gpointer) result->str, (gpointer) result->len,
3224 (gpointer) position, (gpointer) window);
3225 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3229 if (result_len + old_length > 1000) {
3230 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3231 dgettext("hildon-common-strings",
3232 "ckdg_ib_maximum_characters_reached"));
3235 g_string_free (result, TRUE);
3239 text_buffer_insert_text (GtkTextBuffer *buffer,
3242 gint new_text_length,
3243 ModestMsgEditWindow *window)
3245 GString *result = g_string_new ("");
3247 gint result_len = 0;
3248 gboolean changed = FALSE;
3250 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3251 gunichar c = g_utf8_get_char_validated (current, 8);
3252 /* Invalid unichar, stop */
3258 result = g_string_append_c (result, ' ');
3262 result = g_string_append_unichar (result, c);
3268 g_signal_stop_emission_by_name (G_OBJECT (buffer), "insert-text");
3269 g_signal_handlers_block_by_func(G_OBJECT(buffer), G_CALLBACK(text_buffer_insert_text), window);
3270 g_signal_emit_by_name (buffer, "insert-text",
3272 (gpointer) result->str, (gpointer) result->len,
3274 g_signal_handlers_unblock_by_func(G_OBJECT(buffer), G_CALLBACK(text_buffer_insert_text), window);
3277 g_string_free (result, TRUE);
3281 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3284 ModestMsgEditWindowPrivate *priv = NULL;
3286 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3287 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3289 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3292 gtk_widget_show_all (priv->find_toolbar);
3293 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3295 gtk_widget_hide_all (priv->find_toolbar);
3296 gtk_widget_grab_focus (priv->msg_body);
3302 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3304 GtkTextIter *match_start,
3305 GtkTextIter *match_end)
3307 GtkTextIter end_iter;
3308 gchar *str_casefold;
3311 gchar *range_casefold;
3314 gboolean result = FALSE;
3321 gtk_text_iter_forward_to_end (&end_iter);
3323 str_casefold = g_utf8_casefold (str, -1);
3324 str_chars_n = strlen (str);
3326 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3327 range_casefold = g_utf8_casefold (range_text, -1);
3328 range_chars_n = strlen (range_casefold);
3330 if (range_chars_n < str_chars_n) {
3331 g_free (str_casefold);
3332 g_free (range_text);
3333 g_free (range_casefold);
3337 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3338 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3339 if (!g_utf8_collate (range_subtext, str_casefold)) {
3340 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3342 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3343 match_start, match_end, NULL);
3344 g_free (found_text);
3346 g_free (range_subtext);
3350 g_free (str_casefold);
3351 g_free (range_text);
3352 g_free (range_casefold);
3359 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3360 ModestMsgEditWindow *window)
3362 gchar *current_search = NULL;
3363 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3365 GtkTextIter selection_start, selection_end;
3366 GtkTextIter match_start, match_end;
3367 gboolean continue_search = FALSE;
3369 if (message_is_empty (window)) {
3370 g_free (priv->last_search);
3371 priv->last_search = NULL;
3372 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3376 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3377 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3378 g_free (current_search);
3379 g_free (priv->last_search);
3380 priv->last_search = NULL;
3381 /* Information banner about empty search */
3382 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
3386 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3387 continue_search = TRUE;
3389 g_free (priv->last_search);
3390 priv->last_search = g_strdup (current_search);
3393 if (continue_search) {
3394 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3395 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3396 &match_start, &match_end);
3398 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
3400 GtkTextIter buffer_start;
3401 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3402 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3403 &match_start, &match_end);
3405 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
3408 /* Mark as selected the string found in search */
3410 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3411 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3412 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3414 g_free (priv->last_search);
3415 priv->last_search = NULL;
3417 g_free (current_search);
3421 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3422 ModestMsgEditWindow *window)
3424 GtkToggleAction *toggle;
3425 ModestWindowPrivate *parent_priv;
3426 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3428 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
3429 gtk_toggle_action_set_active (toggle, FALSE);
3433 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3435 ModestMsgEditWindowPrivate *priv;
3437 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3442 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3445 ModestMsgEditWindowPrivate *priv;
3447 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3453 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3456 ModestMsgEditWindowPrivate *priv;
3457 TnyHeader *header = NULL;
3459 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3460 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3462 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3463 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3465 if (priv->draft_msg != NULL) {
3466 g_object_unref (priv->draft_msg);
3469 if (draft != NULL) {
3470 g_object_ref (draft);
3471 header = tny_msg_get_header (draft);
3472 if (priv->msg_uid) {
3473 g_free (priv->msg_uid);
3474 priv->msg_uid = NULL;
3476 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3477 if (GTK_WIDGET_REALIZED (window))
3478 modest_window_mgr_register_window (mgr, MODEST_WINDOW (window));
3481 priv->draft_msg = draft;
3485 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3486 GtkTextIter *start, GtkTextIter *end,
3489 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3490 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3493 if (tag == NULL+13) return;
3494 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3495 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3496 replace_with_images (window, priv->images);
3501 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3504 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3506 g_return_if_fail (TNY_IS_MIME_PART (part));
3507 tny_list_prepend (priv->attachments, (GObject *) part);
3508 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3509 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3510 gtk_widget_show_all (priv->attachments_caption);
3511 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3515 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3517 ModestMsgEditWindowPrivate *priv;
3519 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3520 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3522 return priv->msg_uid;
3526 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3527 ModestMsgEditWindowWidgetType widget_type)
3529 ModestMsgEditWindowPrivate *priv;
3531 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3532 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3534 switch (widget_type) {
3535 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3536 return priv->msg_body;
3538 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3539 return priv->to_field;
3541 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3542 return priv->cc_field;
3544 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3545 return priv->bcc_field;
3547 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3548 return priv->subject_field;
3550 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3551 return priv->attachments_view;
3559 remove_tags (WPTextBuffer *buffer)
3561 GtkTextIter start, end;
3563 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3564 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3566 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3570 on_account_removed (TnyAccountStore *account_store,
3571 TnyAccount *account,
3574 /* Do nothing if it's a store account, because we use the
3575 transport to send the messages */
3576 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3577 const gchar *parent_acc = NULL;
3578 const gchar *our_acc = NULL;
3580 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3581 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3582 /* Close this window if I'm showing a message of the removed account */
3583 if (strcmp (parent_acc, our_acc) == 0)
3584 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3589 on_zoom_minus_plus_not_implemented (ModestWindow *window)
3591 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3593 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
3599 set_zoom_do_nothing (ModestWindow *window,
3605 get_zoom_do_nothing (ModestWindow *window)