1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37 #include <tny-vfs-stream.h>
41 #include <modest-account-mgr.h>
42 #include <modest-account-mgr-helpers.h>
44 #include <widgets/modest-msg-edit-window.h>
45 #include <widgets/modest-combo-box.h>
46 #include <widgets/modest-recpt-editor.h>
47 #include <widgets/modest-attachments-view.h>
49 #include <modest-runtime.h>
51 #include "modest-platform.h"
52 #include "modest-icon-names.h"
53 #include "modest-widget-memory.h"
54 #include "modest-window-priv.h"
55 #include "modest-mail-operation.h"
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-tny-folder.h"
59 #include "modest-tny-account.h"
60 #include "modest-address-book.h"
61 #include "modest-text-utils.h"
62 #include <tny-simple-list.h>
63 #include <wptextview.h>
64 #include <wptextbuffer.h>
65 #include "modest-scroll-area.h"
66 #include "modest-msg-edit-window-ui-dimming.h"
68 #include "modest-hildon-includes.h"
69 #ifdef MODEST_HAVE_HILDON0_WIDGETS
70 #include <hildon-widgets/hildon-color-chooser.h>
72 #include "widgets/modest-msg-edit-window-ui.h"
73 #ifdef MODEST_HAVE_HILDON0_WIDGETS
74 #include <libgnomevfs/gnome-vfs-mime-utils.h>
76 #include <libgnomevfs/gnome-vfs-mime.h>
78 #include <modest-utils.h>
79 #include "modest-maemo-utils.h"
82 #define DEFAULT_FONT_SIZE 3
83 #define DEFAULT_FONT 2
84 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
85 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
86 #define DEFAULT_MAIN_VBOX_SPACING 6
87 #define SUBJECT_MAX_LENGTH 1000
88 #define IMAGE_MAX_WIDTH 560
89 #define DEFAULT_FONT_SCALE 1.5
91 static gboolean is_wp_text_buffer_started = FALSE;
93 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
94 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
95 static void modest_msg_edit_window_finalize (GObject *obj);
97 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
98 static void body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
99 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
101 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
102 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
103 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
104 static void text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
105 GtkTextIter *start, GtkTextIter *end,
107 static void text_buffer_insert_text (GtkTextBuffer *buffer,
108 GtkTextIter *location,
111 ModestMsgEditWindow *window);
112 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
113 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
114 static void subject_field_insert_text (GtkEditable *editable,
116 gint new_text_length,
118 ModestMsgEditWindow *window);
119 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
121 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
123 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
125 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
126 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
127 GdkEventWindowState *event,
129 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
130 ModestRecptEditor *editor);
131 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
132 ModestMsgEditWindow *window);
134 /* ModestWindow methods implementation */
135 static void modest_msg_edit_window_disconnect_signals (ModestWindow *window);
136 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
137 gboolean show_toolbar);
138 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
140 ModestMsgEditWindow *window);
141 static void subject_field_move_cursor (GtkEntry *entry,
142 GtkMovementStep step,
146 static void update_window_title (ModestMsgEditWindow *window);
149 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
150 ModestMsgEditWindow *window);
151 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
152 ModestMsgEditWindow *window);
153 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
155 GtkTextIter *match_start,
156 GtkTextIter *match_end);
158 static void remove_tags (WPTextBuffer *buffer);
160 static void on_account_removed (TnyAccountStore *account_store,
164 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
165 static void set_zoom_do_nothing (ModestWindow *window, gdouble zoom);
166 static gdouble get_zoom_do_nothing (ModestWindow *window);
168 static void init_window (ModestMsgEditWindow *obj);
170 gboolean scroll_drag_timeout (gpointer userdata);
171 static void correct_scroll (ModestMsgEditWindow *w);
172 static void correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused);
173 static void text_buffer_end_user_action (GtkTextBuffer *buffer,
174 ModestMsgEditWindow *userdata);
175 static void text_buffer_mark_set (GtkTextBuffer *buffer,
178 ModestMsgEditWindow *userdata);
179 void vadj_changed (GtkAdjustment *adj,
180 ModestMsgEditWindow *window);
182 static ModestPair *find_transport_from_message_sender (ModestPairList *transports,
188 static void DEBUG_BUFFER (WPTextBuffer *buffer)
192 g_message ("BEGIN BUFFER OF SIZE %d", gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (buffer)));
194 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
195 while (!gtk_text_iter_is_end (&iter)) {
196 GString *output = g_string_new ("");
197 GSList *toggled_tags;
200 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
201 g_string_append_printf (output, "%d: CLOSED [ ", gtk_text_iter_get_offset (&iter));
202 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
203 GtkTextTag *tag = (GtkTextTag *) node->data;
205 g_object_get (G_OBJECT (tag), "name", &name, NULL);
206 output = g_string_append (output, name);
207 g_string_append (output, " ");
209 output = g_string_append (output, "] OPENED [ ");
210 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
211 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
212 GtkTextTag *tag = (GtkTextTag *) node->data;
214 g_object_get (G_OBJECT (tag), "name", &name, NULL);
215 output = g_string_append (output, name);
216 g_string_append (output, " ");
218 output = g_string_append (output, "]\n");
219 g_message ("%s", output->str);
220 g_string_free (output, TRUE);
221 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
223 g_message ("END BUFFER");
228 /* static gboolean */
229 /* on_key_pressed (GtkWidget *self, */
230 /* GdkEventKey *event, */
231 /* gpointer user_data); */
233 /* list my signals */
240 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
241 struct _ModestMsgEditWindowPrivate {
244 GtkWidget *header_box;
246 ModestPairList *from_field_protos;
247 GtkWidget *from_field;
248 const gchar *original_account_name;
252 GtkWidget *bcc_field;
253 GtkWidget *subject_field;
254 GtkWidget *attachments_view;
255 GtkWidget *priority_icon;
256 GtkWidget *add_attachment_button;
258 GtkWidget *cc_caption;
259 GtkWidget *bcc_caption;
260 gboolean update_caption_visibility;
261 GtkWidget *attachments_caption;
263 GtkTextBuffer *text_buffer;
265 GtkWidget *font_size_toolitem;
266 GtkWidget *font_face_toolitem;
267 GtkWidget *font_color_button;
268 GSList *font_items_group;
269 GtkWidget *font_tool_button_label;
270 GSList *size_items_group;
271 GtkWidget *size_tool_button_label;
273 GtkWidget *find_toolbar;
277 guint scroll_drag_timeout_id;
281 TnyList *attachments;
286 TnyHeaderFlags priority_flags;
288 gboolean can_undo, can_redo;
289 gulong clipboard_change_handler_id;
290 gulong default_clipboard_change_handler_id;
291 gulong account_removed_handler_id;
292 gchar *clipboard_text;
301 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
302 MODEST_TYPE_MSG_EDIT_WINDOW, \
303 ModestMsgEditWindowPrivate))
305 static GtkWindowClass *parent_class = NULL;
307 /* uncomment the following if you have defined any signals */
308 /* static guint signals[LAST_SIGNAL] = {0}; */
311 modest_msg_edit_window_get_type (void)
313 static GType my_type = 0;
315 static const GTypeInfo my_info = {
316 sizeof(ModestMsgEditWindowClass),
317 NULL, /* base init */
318 NULL, /* base finalize */
319 (GClassInitFunc) modest_msg_edit_window_class_init,
320 NULL, /* class finalize */
321 NULL, /* class data */
322 sizeof(ModestMsgEditWindow),
324 (GInstanceInitFunc) modest_msg_edit_window_init,
327 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
328 "ModestMsgEditWindow",
336 save_state (ModestWindow *self)
338 modest_widget_memory_save (modest_runtime_get_conf(),
339 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
344 restore_settings (ModestMsgEditWindow *self)
346 ModestConf *conf = NULL;
348 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
350 conf = modest_runtime_get_conf ();
351 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
352 "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarNormalScreenMenu");
353 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
354 modest_conf_get_bool (conf, MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR, NULL));
355 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
356 "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarFullScreenMenu");
357 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
358 modest_conf_get_bool (conf, MODEST_CONF_EDIT_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
360 /* set initial state of cc and bcc */
361 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
362 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
363 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
364 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
365 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
366 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
368 /* Dim at start clipboard actions */
369 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
370 gtk_action_set_sensitive (action, FALSE);
371 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
372 gtk_action_set_sensitive (action, FALSE);
373 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
374 gtk_action_set_sensitive (action, FALSE);
376 modest_widget_memory_restore (conf,
377 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
382 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
384 GObjectClass *gobject_class;
385 ModestWindowClass *modest_window_class;
386 gobject_class = (GObjectClass*) klass;
387 modest_window_class = (ModestWindowClass*) klass;
389 parent_class = g_type_class_peek_parent (klass);
390 gobject_class->finalize = modest_msg_edit_window_finalize;
392 modest_window_class->set_zoom_func = set_zoom_do_nothing;
393 modest_window_class->get_zoom_func = get_zoom_do_nothing;
394 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
395 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
396 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
397 modest_window_class->save_state_func = save_state;
398 modest_window_class->disconnect_signals_func = modest_msg_edit_window_disconnect_signals;
400 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
404 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
406 ModestMsgEditWindowPrivate *priv;
407 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
409 priv->msg_body = NULL;
411 priv->from_field = NULL;
412 priv->to_field = NULL;
413 priv->cc_field = NULL;
414 priv->bcc_field = NULL;
415 priv->subject_field = NULL;
416 priv->attachments = TNY_LIST (tny_simple_list_new ());
417 priv->images = TNY_LIST (tny_simple_list_new ());
418 priv->images_size = 0;
419 priv->images_count = 0;
422 priv->cc_caption = NULL;
423 priv->bcc_caption = NULL;
424 priv->update_caption_visibility = FALSE;
426 priv->priority_flags = 0;
428 priv->find_toolbar = NULL;
429 priv->last_search = NULL;
431 priv->draft_msg = NULL;
432 priv->outbox_msg = NULL;
433 priv->msg_uid = NULL;
435 priv->can_undo = FALSE;
436 priv->can_redo = FALSE;
437 priv->clipboard_change_handler_id = 0;
438 priv->default_clipboard_change_handler_id = 0;
439 priv->account_removed_handler_id = 0;
440 priv->clipboard_text = NULL;
443 priv->scroll_drag_timeout_id = 0;
444 priv->last_upper = 0.0;
446 modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
447 GTK_WINDOW(obj),"applications_email_editor");
449 if (!is_wp_text_buffer_started) {
450 is_wp_text_buffer_started = TRUE;
451 wp_text_buffer_library_init ();
456 hildon_program_add_window (hildon_program_get_instance(),
461 /* FIXME: this is a dup from the one in gtk/ */
464 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
466 static ModestPairList*
467 get_transports (void)
469 GSList *transports = NULL;
471 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
472 GSList *accounts = modest_account_mgr_account_names (account_mgr,
473 TRUE /* only enabled accounts. */);
475 GSList *cursor = accounts;
477 gchar *account_name = cursor->data;
478 gchar *from_string = NULL;
480 from_string = modest_account_mgr_get_from_string (account_mgr,
484 if (from_string && account_name) {
485 gchar *name = account_name;
486 ModestPair *pair = modest_pair_new ((gpointer) name,
487 (gpointer) from_string , TRUE);
488 transports = g_slist_prepend (transports, pair);
491 cursor = cursor->next;
493 g_slist_free (accounts); /* only free the accounts, not the elements,
494 * because they are used in the pairlist */
499 * Search an (account, address) ModestPairList for a pair whose
500 * address matches the one in the From: header of a TnyMsg
502 * @result: A ModestPair * with a matching address, or NULL if none found
505 find_transport_from_message_sender (ModestPairList *transports, TnyMsg *msg)
507 g_return_val_if_fail (transports, NULL);
508 g_return_val_if_fail (msg, NULL);
510 ModestPair *account_pair = NULL;
511 TnyHeader *header = tny_msg_get_header (msg);
513 if (header != NULL && tny_header_get_from (header)) {
514 char *from_addr = modest_text_utils_get_email_address (tny_header_get_from (header));
516 for (iter = transports; iter && !account_pair; iter = iter->next) {
517 ModestPair *pair = (ModestPair *) iter->data;
518 char *account_addr = modest_text_utils_get_email_address ((char *) pair->second);
519 if (account_addr && !strcasecmp(from_addr, account_addr)) {
522 g_free (account_addr);
528 g_object_unref (header);
533 static void window_focus (GtkWindow *window,
537 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
541 scroll_drag_timeout (gpointer userdata)
543 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
544 ModestMsgEditWindowPrivate *priv;
546 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
548 correct_scroll_without_drag_check (win, TRUE);
550 priv->scroll_drag_timeout_id = 0;
556 correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused)
558 ModestMsgEditWindowPrivate *priv;
561 GdkRectangle rectangle;
567 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
569 if (only_if_focused && !gtk_widget_is_focus (priv->msg_body))
572 insert = gtk_text_buffer_get_insert (priv->text_buffer);
573 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
575 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
576 vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll));
577 offset = priv->msg_body->allocation.y;
579 new_value = vadj->value;
581 if ((offset + rectangle.y + rectangle.height) >
582 ((gint) (vadj->value +vadj->page_size))) {
583 new_value = (offset + rectangle.y) - vadj->page_size * 0.25;
584 if (new_value > vadj->upper - vadj->page_size)
585 new_value = vadj->upper - vadj->page_size;
586 } else if ((offset + rectangle.y) < ((gint) vadj->value)) {
587 new_value = (offset + rectangle.y - vadj->page_size * 0.75);
588 if (((gint) (new_value + vadj->page_size)) < (offset + rectangle.y + rectangle.height))
589 new_value = offset + rectangle.y + rectangle.height - (gint) vadj->page_size;
592 if (new_value > vadj->value)
593 new_value = vadj->value;
596 if (vadj->value != new_value) {
597 g_signal_emit_by_name (GTK_TEXT_VIEW(priv->msg_body)->layout,
599 vadj->value = new_value;
600 gtk_adjustment_value_changed (vadj);
601 /* invalidate body */
602 window = gtk_widget_get_parent_window (priv->msg_body);
604 gdk_window_invalidate_rect (window, NULL, TRUE);
610 correct_scroll (ModestMsgEditWindow *w)
612 ModestMsgEditWindowPrivate *priv;
614 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
615 if (gtk_grab_get_current () == priv->msg_body) {
616 if (priv->scroll_drag_timeout_id == 0) {
617 priv->scroll_drag_timeout_id = g_timeout_add (500, (GSourceFunc) scroll_drag_timeout,
623 correct_scroll_without_drag_check (w, TRUE);
627 text_buffer_end_user_action (GtkTextBuffer *buffer,
628 ModestMsgEditWindow *userdata)
631 correct_scroll (userdata);
635 text_buffer_mark_set (GtkTextBuffer *buffer,
638 ModestMsgEditWindow *userdata)
640 gtk_text_buffer_begin_user_action (buffer);
641 gtk_text_buffer_end_user_action (buffer);
645 cut_clipboard_check (GtkTextView *text_view,
648 GtkTextBuffer *buffer;
650 buffer = gtk_text_view_get_buffer (text_view);
651 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
652 g_signal_stop_emission_by_name ((gpointer )text_view, "cut-clipboard");
657 copy_clipboard_check (GtkTextView *text_view,
660 GtkTextBuffer *buffer;
662 buffer = gtk_text_view_get_buffer (text_view);
663 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
664 g_signal_stop_emission_by_name ((gpointer )text_view, "copy-clipboard");
668 void vadj_changed (GtkAdjustment *adj,
669 ModestMsgEditWindow *window)
671 ModestMsgEditWindowPrivate *priv;
673 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
675 if (priv->last_upper != adj->upper) {
676 priv->last_upper = adj->upper;
677 correct_scroll (window);
682 connect_signals (ModestMsgEditWindow *obj)
684 ModestMsgEditWindowPrivate *priv;
686 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
688 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
689 G_CALLBACK (text_buffer_refresh_attributes), obj);
690 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
691 G_CALLBACK (text_buffer_can_undo), obj);
692 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
693 G_CALLBACK (text_buffer_can_redo), obj);
694 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
695 G_CALLBACK (body_changed), obj);
696 g_signal_connect (G_OBJECT (priv->text_buffer), "insert-text",
697 G_CALLBACK (text_buffer_insert_text), obj);
698 g_signal_connect (G_OBJECT (obj), "window-state-event",
699 G_CALLBACK (modest_msg_edit_window_window_state_event),
701 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
702 G_CALLBACK (text_buffer_end_user_action), obj);
703 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
704 G_CALLBACK (text_buffer_mark_set), obj);
705 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
706 G_CALLBACK (text_buffer_apply_tag), obj);
707 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
708 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
709 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
710 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
711 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
712 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
714 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
715 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
717 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
718 G_CALLBACK (msg_body_focus), obj);
719 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
720 G_CALLBACK (msg_body_focus), obj);
721 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
722 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
723 "changed", G_CALLBACK (recpt_field_changed), obj);
724 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
725 "changed", G_CALLBACK (recpt_field_changed), obj);
726 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
727 "changed", G_CALLBACK (recpt_field_changed), obj);
728 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
729 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
730 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
732 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
733 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
735 g_signal_connect (G_OBJECT (gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll))),
737 G_CALLBACK (vadj_changed),
740 priv->clipboard_change_handler_id =
741 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
742 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
743 priv->default_clipboard_change_handler_id =
744 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
745 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
747 g_signal_connect (G_OBJECT (priv->msg_body), "cut-clipboard", G_CALLBACK (cut_clipboard_check), NULL);
748 g_signal_connect (G_OBJECT (priv->msg_body), "copy-clipboard", G_CALLBACK (copy_clipboard_check), NULL);
753 init_window (ModestMsgEditWindow *obj)
755 GtkWidget *from_caption, *to_caption, *subject_caption;
756 GtkWidget *main_vbox;
757 ModestMsgEditWindowPrivate *priv;
758 GtkActionGroup *action_group;
759 ModestWindowPrivate *parent_priv;
760 GdkPixbuf *window_icon = NULL;
761 GError *error = NULL;
763 GtkSizeGroup *size_group;
764 GtkWidget *subject_box;
765 GtkWidget *attachment_icon;
766 GtkWidget *window_box;
767 #if (GTK_MINOR_VERSION >= 10)
768 GdkAtom deserialize_type;
770 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
771 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
773 parent_priv->ui_manager = gtk_ui_manager_new();
774 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
775 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
777 /* Add common actions */
778 gtk_action_group_add_actions (action_group,
779 modest_msg_edit_action_entries,
780 G_N_ELEMENTS (modest_msg_edit_action_entries),
782 gtk_action_group_add_toggle_actions (action_group,
783 modest_msg_edit_toggle_action_entries,
784 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
786 gtk_action_group_add_radio_actions (action_group,
787 modest_msg_edit_alignment_radio_action_entries,
788 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
790 G_CALLBACK (modest_ui_actions_on_change_justify),
792 gtk_action_group_add_radio_actions (action_group,
793 modest_msg_edit_priority_action_entries,
794 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
796 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
798 gtk_action_group_add_radio_actions (action_group,
799 modest_msg_edit_file_format_action_entries,
800 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
801 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
802 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
804 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
805 g_object_unref (action_group);
807 /* Load the UI definition */
808 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
811 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
812 g_clear_error (&error);
815 /* Add accelerators */
816 gtk_window_add_accel_group (GTK_WINDOW (obj),
817 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
819 parent_priv->menubar = NULL;
821 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
823 /* Note: This ModestPairList* must exist for as long as the combo
824 * that uses it, because the ModestComboBox uses the ID opaquely,
825 * so it can't know how to manage its memory. */
826 priv->from_field = modest_combo_box_new (NULL, g_str_equal);
828 priv->to_field = modest_recpt_editor_new ();
829 priv->cc_field = modest_recpt_editor_new ();
830 priv->bcc_field = modest_recpt_editor_new ();
831 subject_box = gtk_hbox_new (FALSE, 0);
832 priv->priority_icon = gtk_image_new ();
833 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
834 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
835 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
836 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
837 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
838 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
839 priv->add_attachment_button = gtk_button_new ();
840 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
841 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
842 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
843 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
844 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
845 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
846 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
847 priv->attachments_view = modest_attachments_view_new (NULL);
849 priv->header_box = gtk_vbox_new (FALSE, 0);
851 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
852 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
853 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
854 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
855 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
856 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
857 g_object_unref (size_group);
859 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
860 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
861 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
862 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
863 gtk_size_group_add_widget (size_group, priv->subject_field);
864 gtk_size_group_add_widget (size_group, priv->attachments_view);
865 g_object_unref (size_group);
867 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
868 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
869 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
870 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
871 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
872 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
873 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
876 priv->msg_body = wp_text_view_new ();
877 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
878 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
879 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
880 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
881 #if (GTK_MINOR_VERSION >= 10)
882 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
883 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
885 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
886 deserialize_type, TRUE);
888 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
890 priv->find_toolbar = hildon_find_toolbar_new (NULL);
891 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
893 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
895 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
896 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
897 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
898 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->scroll), TRUE);
900 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
902 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
903 priv->frame = gtk_frame_new (NULL);
904 gtk_box_pack_start (GTK_BOX(main_vbox), priv->frame, TRUE, TRUE, 0);
906 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
907 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
908 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
910 window_box = gtk_vbox_new (FALSE, 0);
911 gtk_container_add (GTK_CONTAINER(obj), window_box);
913 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
915 gtk_container_add (GTK_CONTAINER (priv->frame), priv->msg_body);
917 /* Set window icon */
918 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
920 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
921 g_object_unref (window_icon);
926 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
928 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
930 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
931 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
932 priv->clipboard_change_handler_id))
933 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
934 priv->clipboard_change_handler_id);
935 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
936 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
937 priv->default_clipboard_change_handler_id))
938 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
939 priv->default_clipboard_change_handler_id);
941 if (priv->account_removed_handler_id &&
942 g_signal_handler_is_connected (modest_runtime_get_account_store (),
943 priv->account_removed_handler_id))
944 g_signal_handler_disconnect(modest_runtime_get_account_store (),
945 priv->account_removed_handler_id);
949 modest_msg_edit_window_finalize (GObject *obj)
951 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
953 /* Sanity check: shouldn't be needed, the window mgr should
954 call this function before */
955 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
957 if (priv->clipboard_text != NULL) {
958 g_free (priv->clipboard_text);
959 priv->clipboard_text = NULL;
962 if (priv->draft_msg != NULL) {
963 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
964 if (TNY_IS_HEADER (header)) {
965 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
966 modest_window_mgr_unregister_header (mgr, header);
968 g_object_unref (priv->draft_msg);
969 priv->draft_msg = NULL;
971 if (priv->outbox_msg != NULL) {
972 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
973 if (TNY_IS_HEADER (header)) {
974 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
975 modest_window_mgr_unregister_header (mgr, header);
977 g_object_unref (priv->outbox_msg);
978 priv->outbox_msg = NULL;
980 if (priv->scroll_drag_timeout_id > 0) {
981 g_source_remove (priv->scroll_drag_timeout_id);
982 priv->scroll_drag_timeout_id = 0;
984 g_free (priv->msg_uid);
985 g_free (priv->last_search);
986 g_slist_free (priv->font_items_group);
987 g_slist_free (priv->size_items_group);
988 g_object_unref (priv->attachments);
989 g_object_unref (priv->images);
991 /* This had to stay alive for as long as the combobox that used it: */
992 modest_pair_list_free (priv->from_field_protos);
994 G_OBJECT_CLASS(parent_class)->finalize (obj);
998 pixbuf_from_stream (TnyStream *stream, const gchar *mime_type, guint64 *stream_size)
1000 GdkPixbufLoader *loader;
1006 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1008 if (loader == NULL) {
1014 tny_stream_reset (TNY_STREAM (stream));
1015 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1016 GError *error = NULL;
1017 unsigned char read_buffer[128];
1019 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1021 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, &error)) {
1026 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1028 g_object_ref (pixbuf);
1029 gdk_pixbuf_loader_close (loader, NULL);
1030 g_object_unref (loader);
1035 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1036 GdkPixbuf *new_pixbuf;
1038 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1039 gdk_pixbuf_get_width (pixbuf);
1040 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1041 g_object_unref (pixbuf);
1042 pixbuf = new_pixbuf;
1046 *stream_size = size;
1052 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1054 ModestMsgEditWindowPrivate *priv;
1057 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1059 for (iter = tny_list_create_iterator (attachments);
1060 !tny_iterator_is_done (iter);
1061 tny_iterator_next (iter)) {
1062 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1063 const gchar *cid = tny_mime_part_get_content_id (part);
1064 const gchar *mime_type = tny_mime_part_get_content_type (part);
1065 if ((cid != NULL)&&(mime_type != NULL)) {
1066 guint64 stream_size;
1067 TnyStream *stream = tny_mime_part_get_decoded_stream (part);
1068 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
1071 g_object_unref (stream);
1073 if (pixbuf != NULL) {
1074 priv->images_count ++;
1075 priv->images_size += stream_size;
1076 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1077 g_object_unref (pixbuf);
1080 g_object_unref (part);
1082 g_object_unref (iter);
1086 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1088 TnyMimePart *parent = NULL;
1089 const gchar *content_type = NULL;
1090 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1092 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1094 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1095 parent = g_object_ref (msg);
1096 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1097 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1100 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1101 iter = tny_list_create_iterator (parts);
1102 while (!tny_iterator_is_done (iter)) {
1104 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1105 content_type = tny_mime_part_get_content_type (part);
1106 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1110 g_object_unref (part);
1112 tny_iterator_next (iter);
1114 g_object_unref (iter);
1115 g_object_unref (parts);
1118 if (parent != NULL) {
1119 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1122 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1123 iter = tny_list_create_iterator (parts);
1124 while (!tny_iterator_is_done (iter)) {
1126 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1127 content_type = tny_mime_part_get_content_type (part);
1128 if (content_type && g_str_has_prefix (content_type, "image/")) {
1129 tny_list_prepend (priv->images, (GObject *) part);
1131 g_object_unref (part);
1132 tny_iterator_next (iter);
1134 g_object_unref (iter);
1135 g_object_unref (parts);
1136 g_object_unref (parent);
1141 update_last_cid (ModestMsgEditWindow *self, TnyList *attachments)
1144 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1146 for (iter = tny_list_create_iterator (attachments) ;
1147 !tny_iterator_is_done (iter);
1148 tny_iterator_next (iter)) {
1149 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1150 const gchar *cid = tny_mime_part_get_content_id (part);
1152 char *invalid = NULL;
1153 gint int_cid = strtol (cid, &invalid, 10);
1154 if ((invalid != NULL) && (*invalid == '\0') && (int_cid > priv->last_cid)) {
1155 priv->last_cid = int_cid;
1158 g_object_unref (part);
1160 g_object_unref (iter);
1164 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1167 const gchar *to, *cc, *bcc, *subject;
1169 ModestMsgEditWindowPrivate *priv;
1171 TnyHeaderFlags priority_flags;
1172 TnyFolder *msg_folder;
1173 gboolean is_html = FALSE;
1175 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1176 g_return_if_fail (TNY_IS_MSG (msg));
1178 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1180 header = tny_msg_get_header (msg);
1181 to = tny_header_get_to (header);
1182 cc = tny_header_get_cc (header);
1183 bcc = tny_header_get_bcc (header);
1184 subject = tny_header_get_subject (header);
1185 priority_flags = tny_header_get_priority (header);
1188 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1190 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1191 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1192 gtk_widget_show (priv->cc_caption);
1193 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1194 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1195 gtk_widget_hide (priv->cc_caption);
1198 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1199 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1200 gtk_widget_show (priv->bcc_caption);
1201 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1202 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1203 gtk_widget_hide (priv->bcc_caption);
1206 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1207 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1210 update_window_title (self);
1212 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1213 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1215 if ((body == NULL)||(body[0] == '\0')) {
1217 body = modest_text_utils_convert_to_html ("");
1220 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1221 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1224 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1227 /* Add attachments to the view */
1228 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1229 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1230 if (tny_list_get_length (priv->attachments) == 0) {
1231 gtk_widget_hide (priv->attachments_caption);
1233 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1234 gtk_widget_show_all (priv->attachments_caption);
1236 get_related_images (self, msg);
1237 update_last_cid (self, priv->attachments);
1238 update_last_cid (self, priv->images);
1239 replace_with_images (self, priv->images);
1241 if (preserve_is_rich && !is_html) {
1242 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1243 /* Get the default format required from configuration */
1244 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1245 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1248 /* Set the default focus depending on having already a To: field or not */
1249 if ((!to)||(*to == '\0')) {
1250 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1252 gtk_widget_grab_focus (priv->msg_body);
1255 /* TODO: lower priority, select in the From: combo to the
1256 value that comes from msg <- not sure, should it be
1259 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1261 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1262 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1264 modest_msg_edit_window_set_modified (self, FALSE);
1266 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1267 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1268 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1269 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1271 if (priv->msg_uid) {
1272 g_free (priv->msg_uid);
1273 priv->msg_uid = NULL;
1276 /* we should set a reference to the incoming message if it is a draft */
1277 msg_folder = tny_msg_get_folder (msg);
1279 if (modest_tny_folder_is_local_folder (msg_folder)) {
1280 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1281 if (type == TNY_FOLDER_TYPE_INVALID)
1282 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1284 if (type == TNY_FOLDER_TYPE_DRAFTS)
1285 priv->draft_msg = g_object_ref(msg);
1286 if (type == TNY_FOLDER_TYPE_OUTBOX)
1287 priv->outbox_msg = g_object_ref(msg);
1288 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1290 g_object_unref (msg_folder);
1295 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
1298 GList *item_children, *node;
1299 GtkWidget *bin_child;
1301 bin_child = gtk_bin_get_child (GTK_BIN(item));
1303 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
1305 for (node = item_children; node != NULL; node = g_list_next (node)) {
1306 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
1307 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
1310 g_list_free (item_children);
1314 menu_tool_button_dont_expand (GtkMenuToolButton *item)
1317 GList *item_children, *node;
1319 box = gtk_bin_get_child (GTK_BIN (item));
1320 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
1321 item_children = gtk_container_get_children (GTK_CONTAINER (box));
1323 for (node = item_children; node != NULL; node = g_list_next (node)) {
1324 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
1325 if (GTK_IS_TOGGLE_BUTTON (node->data))
1326 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
1327 else if (GTK_IS_BUTTON (node->data))
1328 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
1330 g_list_free (item_children);
1335 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1337 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1338 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1339 GtkWidget *placeholder;
1340 GtkWidget *tool_item;
1345 GtkWidget *sizes_menu;
1346 GtkWidget *fonts_menu;
1347 GSList *radio_group = NULL;
1348 GSList *node = NULL;
1352 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1353 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1355 /* Font color placeholder */
1356 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1357 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1360 tool_item = GTK_WIDGET (gtk_tool_item_new ());
1361 priv->font_color_button = hildon_color_button_new ();
1362 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
1363 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1364 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
1365 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1366 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1367 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1368 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1370 G_CALLBACK (modest_msg_edit_window_color_button_change),
1373 /* Font size and face placeholder */
1374 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1375 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1377 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1378 priv->size_tool_button_label = gtk_label_new (NULL);
1379 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1380 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1381 size_text,"</span>", NULL);
1382 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1384 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
1385 sizes_menu = gtk_menu_new ();
1386 priv->size_items_group = NULL;
1388 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1389 GtkWidget *size_menu_item;
1391 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1392 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
1393 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
1394 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
1395 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
1396 gtk_widget_show (size_menu_item);
1398 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
1402 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1403 GtkWidget *item = (GtkWidget *) node->data;
1404 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
1408 priv->size_items_group = g_slist_reverse (priv->size_items_group);
1409 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
1410 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1411 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1412 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1413 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1414 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1415 priv->font_size_toolitem = tool_item;
1418 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1419 priv->font_tool_button_label = gtk_label_new (NULL);
1420 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1421 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1423 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
1424 fonts_menu = gtk_menu_new ();
1425 priv->font_items_group = NULL;
1427 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1428 GtkWidget *font_menu_item;
1429 GtkWidget *child_label;
1431 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
1432 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
1433 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
1434 wp_get_font_name (font_index), "</span>", NULL);
1435 gtk_label_set_markup (GTK_LABEL (child_label), markup);
1438 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
1439 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
1440 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
1441 gtk_widget_show (font_menu_item);
1443 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
1446 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1447 GtkWidget *item = (GtkWidget *) node->data;
1448 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
1451 priv->font_items_group = g_slist_reverse (priv->font_items_group);
1452 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
1453 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1454 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1455 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1456 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1457 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1458 priv->font_face_toolitem = tool_item;
1460 /* Set expand and homogeneous for remaining items */
1461 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1462 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1463 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1464 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1465 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1466 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1467 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1468 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1469 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1471 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1472 will not show the tool items added to the placeholders) */
1473 gtk_widget_show_all (parent_priv->toolbar);
1475 /* Set the no show all *after* showing all items. We do not
1476 want the toolbar to be shown with a show all because it
1477 could go agains the gconf setting regarding showing or not
1478 the toolbar of the editor window */
1479 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1485 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean preserve_is_rich)
1488 ModestWindowPrivate *parent_priv;
1489 ModestMsgEditWindowPrivate *priv;
1490 ModestPair *account_pair = NULL;
1491 ModestDimmingRulesGroup *menu_rules_group = NULL;
1492 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1493 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1494 ModestWindowMgr *mgr = NULL;
1496 g_return_val_if_fail (msg, NULL);
1497 g_return_val_if_fail (account_name, NULL);
1499 mgr = modest_runtime_get_window_mgr ();
1501 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1503 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1504 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1506 /* Menubar. Update the state of some toggles */
1507 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1508 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
1509 priv->from_field_protos = get_transports ();
1510 modest_combo_box_set_pair_list (MODEST_COMBO_BOX (priv->from_field), priv->from_field_protos);
1511 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1512 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1515 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1517 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1519 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1521 account_pair = find_transport_from_message_sender (priv->from_field_protos, msg);
1522 if (account_pair == NULL) {
1523 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
1525 if (account_pair != NULL)
1526 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
1528 priv->original_account_name = account_pair ? (const gchar *) account_pair->first : NULL;
1530 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new ();
1531 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1532 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1533 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1534 /* Add common dimming rules */
1535 modest_dimming_rules_group_add_rules (menu_rules_group,
1536 modest_msg_edit_window_menu_dimming_entries,
1537 G_N_ELEMENTS (modest_msg_edit_window_menu_dimming_entries),
1538 MODEST_WINDOW (obj));
1539 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1540 modest_msg_edit_window_toolbar_dimming_entries,
1541 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1542 MODEST_WINDOW (obj));
1543 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_button,
1544 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1545 MODEST_WINDOW (obj));
1546 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1547 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1548 MODEST_WINDOW (obj));
1549 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1550 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1551 MODEST_WINDOW (obj));
1552 modest_dimming_rules_group_add_rules (clipboard_rules_group,
1553 modest_msg_edit_window_clipboard_dimming_entries,
1554 G_N_ELEMENTS (modest_msg_edit_window_clipboard_dimming_entries),
1555 MODEST_WINDOW (obj));
1556 /* Insert dimming rules group for this window */
1557 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1558 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1559 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1560 /* Checks the dimming rules */
1561 g_object_unref (menu_rules_group);
1562 g_object_unref (toolbar_rules_group);
1563 g_object_unref (clipboard_rules_group);
1564 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, MODEST_MSG_EDIT_WINDOW (obj));
1566 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1568 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1570 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1571 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1572 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1573 priv->update_caption_visibility = TRUE;
1575 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1577 /* Track account-removed signal, this window should be closed
1578 in the case we're creating a mail associated to the account
1580 priv->account_removed_handler_id =
1581 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1583 G_CALLBACK(on_account_removed),
1586 return (ModestWindow*) obj;
1590 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1592 GString **string_buffer = (GString **) user_data;
1594 *string_buffer = g_string_append (*string_buffer, buffer);
1600 * @result: A new string which should be freed with g_free().
1603 get_formatted_data (ModestMsgEditWindow *edit_window)
1605 ModestMsgEditWindowPrivate *priv;
1606 GString *string_buffer = g_string_new ("");
1608 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1610 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1612 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1614 return g_string_free (string_buffer, FALSE);
1619 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1622 const gchar *account_name;
1623 ModestMsgEditWindowPrivate *priv;
1624 TnyIterator *att_iter;
1626 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1628 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1630 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1631 g_return_val_if_fail (account_name, NULL);
1634 /* don't free these (except from) */
1635 data = g_slice_new0 (MsgData);
1636 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1638 data->account_name = g_strdup (account_name);
1639 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1640 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1641 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1642 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1643 if (priv->draft_msg) {
1644 data->draft_msg = g_object_ref (priv->draft_msg);
1645 } else if (priv->outbox_msg) {
1646 data->draft_msg = g_object_ref (priv->outbox_msg);
1648 data->draft_msg = NULL;
1651 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1653 gtk_text_buffer_get_bounds (buf, &b, &e);
1654 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1656 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1657 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1659 data->html_body = NULL;
1661 /* deep-copy the data */
1662 att_iter = tny_list_create_iterator (priv->attachments);
1663 data->attachments = NULL;
1664 while (!tny_iterator_is_done (att_iter)) {
1665 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1666 if (!(TNY_IS_MIME_PART(part))) {
1667 g_warning ("strange data in attachment list");
1668 g_object_unref (part);
1669 tny_iterator_next (att_iter);
1672 data->attachments = g_list_append (data->attachments,
1674 tny_iterator_next (att_iter);
1676 g_object_unref (att_iter);
1678 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1679 att_iter = tny_list_create_iterator (priv->images);
1680 data->images = NULL;
1681 while (!tny_iterator_is_done (att_iter)) {
1682 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1684 if (!(TNY_IS_MIME_PART(part))) {
1685 g_warning ("strange data in attachment list");
1686 g_object_unref (part);
1687 tny_iterator_next (att_iter);
1690 cid = tny_mime_part_get_content_id (part);
1692 gchar *image_tag_id;
1693 GtkTextTag *image_tag;
1695 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1696 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1697 g_free (image_tag_id);
1699 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1701 ((gtk_text_iter_has_tag (&iter, image_tag))||
1702 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1703 data->images = g_list_append (data->images,
1704 g_object_ref (part));
1706 g_object_unref (part);
1707 tny_iterator_next (att_iter);
1709 g_object_unref (att_iter);
1711 data->priority_flags = priv->priority_flags;
1718 unref_gobject (GObject *obj, gpointer data)
1720 if (!G_IS_OBJECT(obj))
1722 g_object_unref (obj);
1726 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1729 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1737 g_free (data->from);
1738 g_free (data->subject);
1739 g_free (data->plain_body);
1740 g_free (data->html_body);
1741 g_free (data->account_name);
1743 if (data->draft_msg != NULL) {
1744 g_object_unref (data->draft_msg);
1745 data->draft_msg = NULL;
1748 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1749 g_list_free (data->attachments);
1750 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1751 g_list_free (data->images);
1753 g_slice_free (MsgData, data);
1757 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1759 guint64 *parts_size)
1761 ModestMsgEditWindowPrivate *priv;
1763 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1765 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1767 /* TODO: add images */
1768 *parts_size += priv->images_size;
1769 *parts_count += priv->images_count;
1774 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1777 ModestMsgEditWindowPrivate *priv = NULL;
1778 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1780 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1782 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1784 return MODEST_MSG_EDIT_FORMAT_HTML;
1786 return MODEST_MSG_EDIT_FORMAT_TEXT;
1790 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1791 ModestMsgEditFormat format)
1793 ModestMsgEditWindowPrivate *priv;
1795 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1796 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1799 case MODEST_MSG_EDIT_FORMAT_HTML:
1800 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1802 case MODEST_MSG_EDIT_FORMAT_TEXT:
1803 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1806 g_return_if_reached ();
1810 ModestMsgEditFormatState *
1811 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1813 ModestMsgEditFormatState *format_state = NULL;
1814 ModestMsgEditWindowPrivate *priv;
1815 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1817 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1818 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1820 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1822 format_state = g_new0 (ModestMsgEditFormatState, 1);
1823 format_state->bold = buffer_format->bold&0x1;
1824 format_state->italics = buffer_format->italic&0x1;
1825 format_state->bullet = buffer_format->bullet&0x1;
1826 format_state->color = buffer_format->color;
1827 format_state->font_size = buffer_format->font_size;
1828 format_state->font_family = wp_get_font_name (buffer_format->font);
1829 format_state->justification = buffer_format->justification;
1830 g_free (buffer_format);
1832 return format_state;
1837 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1838 const ModestMsgEditFormatState *format_state)
1840 ModestMsgEditWindowPrivate *priv;
1841 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1842 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1843 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1844 g_return_if_fail (format_state != NULL);
1846 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1847 gtk_widget_grab_focus (priv->msg_body);
1848 buffer_format->bold = (format_state->bold != FALSE);
1849 buffer_format->italic = (format_state->italics != FALSE);
1850 buffer_format->color = format_state->color;
1851 buffer_format->font_size = format_state->font_size;
1852 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1853 buffer_format->justification = format_state->justification;
1854 buffer_format->bullet = format_state->bullet;
1856 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1858 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1859 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1860 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1861 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1862 buffer_format->cs.font = (buffer_format->font != current_format->font);
1863 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1864 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1866 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1867 if (buffer_format->cs.bold) {
1868 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1869 GINT_TO_POINTER (buffer_format->bold&0x1));
1871 if (buffer_format->cs.italic) {
1872 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1873 GINT_TO_POINTER (buffer_format->italic&0x1));
1875 if (buffer_format->cs.color) {
1876 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1877 GINT_TO_POINTER (&(buffer_format->color)));
1879 if (buffer_format->cs.font_size) {
1880 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1881 GINT_TO_POINTER (buffer_format->font_size));
1883 if (buffer_format->cs.justification) {
1884 switch (buffer_format->justification) {
1885 case GTK_JUSTIFY_LEFT:
1886 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1887 GINT_TO_POINTER(TRUE));
1889 case GTK_JUSTIFY_CENTER:
1890 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1891 GINT_TO_POINTER(TRUE));
1893 case GTK_JUSTIFY_RIGHT:
1894 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1895 GINT_TO_POINTER(TRUE));
1902 if (buffer_format->cs.font) {
1903 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1904 GINT_TO_POINTER (buffer_format->font));
1906 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1907 if (buffer_format->cs.bullet) {
1908 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
1909 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
1911 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1913 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
1915 g_free (current_format);
1920 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1922 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1924 ModestWindowPrivate *parent_priv;
1925 ModestMsgEditWindowPrivate *priv;
1926 GtkWidget *new_size_menuitem;
1927 GtkWidget *new_font_menuitem;
1929 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1930 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1932 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1933 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1934 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1935 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1937 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1938 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1939 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1942 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1944 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1945 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1947 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1948 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1950 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
1951 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
1954 switch (buffer_format->justification)
1956 case GTK_JUSTIFY_LEFT:
1957 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1959 case GTK_JUSTIFY_CENTER:
1960 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1962 case GTK_JUSTIFY_RIGHT:
1963 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1970 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1972 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1973 G_CALLBACK (modest_msg_edit_window_color_button_change),
1975 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1976 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1977 G_CALLBACK (modest_msg_edit_window_color_button_change),
1980 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1981 buffer_format->font_size))->data);
1982 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1986 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1987 markup = g_strconcat ("<span font_family='Sans'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1988 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1990 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1991 G_CALLBACK (modest_msg_edit_window_size_change),
1993 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1994 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1995 G_CALLBACK (modest_msg_edit_window_size_change),
1999 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
2000 buffer_format->font))->data);
2001 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
2005 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
2006 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2007 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2009 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
2010 G_CALLBACK (modest_msg_edit_window_font_change),
2012 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
2013 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
2014 G_CALLBACK (modest_msg_edit_window_font_change),
2018 g_free (buffer_format);
2022 #ifdef MODEST_HILDON_VERSION_0
2024 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2027 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2028 ModestMsgEditWindowPrivate *priv;
2029 GtkWidget *dialog = NULL;
2031 GdkColor *new_color = NULL;
2033 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2034 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2036 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2037 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2038 g_free (buffer_format);
2040 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2041 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2042 if (new_color != NULL) {
2043 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2044 (gpointer) new_color);
2047 gtk_widget_destroy (dialog);
2052 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2055 ModestMsgEditWindowPrivate *priv;
2056 GtkWidget *dialog = NULL;
2058 GdkColor *old_color = NULL;
2059 const GdkColor *new_color = NULL;
2061 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2062 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2064 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2065 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2067 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2068 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2069 if (new_color != NULL)
2070 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2072 gtk_widget_destroy (dialog);
2078 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2081 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2082 ModestMsgEditWindowPrivate *priv;
2083 GtkWidget *dialog = NULL;
2085 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2086 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2088 dialog = hildon_color_chooser_new ();
2089 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2090 g_free (buffer_format);
2092 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2094 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2095 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2098 gtk_widget_destroy (dialog);
2103 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2106 ModestMsgEditWindowPrivate *priv;
2107 GtkWidget *dialog = NULL;
2108 GdkColor *old_color = NULL;
2110 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2111 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2113 dialog = hildon_color_chooser_new ();
2114 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2116 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2118 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2119 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2121 gtk_widget_destroy (dialog);
2124 #endif /*!MODEST_HILDON_VERSION_0*/
2128 static TnyStream* create_stream_for_uri (const gchar* uri)
2133 TnyStream *result = NULL;
2135 GnomeVFSHandle *handle = NULL;
2136 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2137 if (test == GNOME_VFS_OK) {
2138 /* Create the tinymail stream: */
2139 /* Presumably tinymai will call gnome_vfs_close (handle) later. */
2140 result = TNY_STREAM (tny_vfs_stream_new (handle));
2147 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2150 ModestMsgEditWindowPrivate *priv;
2151 GtkWidget *dialog = NULL;
2153 GSList *uris = NULL;
2154 GSList *uri_node = NULL;
2156 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2158 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2159 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2160 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2162 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2164 response = gtk_dialog_run (GTK_DIALOG (dialog));
2166 case GTK_RESPONSE_OK:
2167 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2172 gtk_widget_destroy (dialog);
2174 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2176 GnomeVFSHandle *handle = NULL;
2177 GnomeVFSResult result;
2178 GtkTextIter position;
2179 GtkTextMark *insert_mark;
2181 uri = (const gchar *) uri_node->data;
2182 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2183 if (result == GNOME_VFS_OK) {
2185 GnomeVFSFileInfo *info;
2186 gchar *filename, *basename, *escaped_filename;
2187 TnyMimePart *mime_part;
2189 const gchar *mime_type = NULL;
2190 GnomeVFSURI *vfs_uri;
2191 guint64 stream_size;
2193 vfs_uri = gnome_vfs_uri_new (uri);
2195 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2196 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2197 g_free (escaped_filename);
2198 gnome_vfs_uri_unref (vfs_uri);
2199 info = gnome_vfs_file_info_new ();
2201 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2202 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2204 mime_type = gnome_vfs_file_info_get_mime_type (info);
2206 mime_part = tny_platform_factory_new_mime_part
2207 (modest_runtime_get_platform_factory ());
2209 TnyStream *stream = create_stream_for_uri (uri);
2210 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2212 content_id = g_strdup_printf ("%d", priv->last_cid);
2213 tny_mime_part_set_content_id (mime_part, content_id);
2214 g_free (content_id);
2217 basename = g_path_get_basename (filename);
2218 tny_mime_part_set_filename (mime_part, basename);
2221 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
2223 if (pixbuf != NULL) {
2224 priv->images_size += stream_size;
2225 priv->images_count ++;
2226 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2227 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2228 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
2231 tny_list_prepend (priv->images, (GObject *) mime_part);
2232 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2234 g_object_unref (mime_part);
2235 gnome_vfs_file_info_unref (info);
2244 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2246 GtkWidget *dialog = NULL;
2248 GSList *uris = NULL;
2251 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2252 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2253 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2255 response = gtk_dialog_run (GTK_DIALOG (dialog));
2257 case GTK_RESPONSE_OK:
2258 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2263 gtk_widget_destroy (dialog);
2265 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2266 const gchar *uri = (const gchar *) uri_node->data;
2267 modest_msg_edit_window_attach_file_one (window, uri);
2269 g_slist_foreach (uris, (GFunc) g_free, NULL);
2270 g_slist_free (uris);
2274 modest_msg_edit_window_attach_file_one (
2275 ModestMsgEditWindow *window,
2278 GnomeVFSHandle *handle = NULL;
2279 ModestMsgEditWindowPrivate *priv;
2280 GnomeVFSResult result;
2282 g_return_if_fail (window);
2283 g_return_if_fail (uri);
2285 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2287 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2288 if (result == GNOME_VFS_OK) {
2289 TnyMimePart *mime_part;
2291 const gchar *mime_type = NULL;
2293 gchar *escaped_filename;
2296 GnomeVFSFileInfo *info;
2297 GnomeVFSURI *vfs_uri;
2299 vfs_uri = gnome_vfs_uri_new (uri);
2302 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2303 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2304 g_free (escaped_filename);
2305 gnome_vfs_uri_unref (vfs_uri);
2307 info = gnome_vfs_file_info_new ();
2309 if (gnome_vfs_get_file_info (uri,
2311 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2313 mime_type = gnome_vfs_file_info_get_mime_type (info);
2314 mime_part = tny_platform_factory_new_mime_part
2315 (modest_runtime_get_platform_factory ());
2316 stream = TNY_STREAM (tny_vfs_stream_new (handle));
2318 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2320 g_object_unref (stream);
2322 content_id = g_strdup_printf ("%d", priv->last_cid);
2323 tny_mime_part_set_content_id (mime_part, content_id);
2324 g_free (content_id);
2327 basename = g_path_get_basename (filename);
2328 tny_mime_part_set_filename (mime_part, basename);
2331 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2332 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2334 info->size == 0, info->size);
2335 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2336 gtk_widget_show_all (priv->attachments_caption);
2337 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2339 g_object_unref (mime_part);
2340 gnome_vfs_file_info_unref (info);
2345 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2348 ModestMsgEditWindowPrivate *priv;
2351 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2352 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2354 if (att_list == NULL) {
2355 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2357 g_object_ref (att_list);
2360 if (tny_list_get_length (att_list) == 0) {
2361 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2363 GtkWidget *confirmation_dialog = NULL;
2364 gboolean dialog_response;
2365 gchar *message = NULL;
2366 gchar *filename = NULL;
2368 if (tny_list_get_length (att_list) == 1) {
2370 iter = tny_list_create_iterator (att_list);
2371 part = (TnyMimePart *) tny_iterator_get_current (iter);
2372 g_object_unref (iter);
2373 if (TNY_IS_MSG (part)) {
2374 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2376 filename = g_strdup (tny_header_get_subject (header));
2377 g_object_unref (header);
2379 if (filename == NULL) {
2380 filename = g_strdup (_("mail_va_no_subject"));
2383 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2385 g_object_unref (part);
2387 filename = g_strdup ("");
2389 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
2390 (tny_list_get_length (att_list) == 1)), filename);
2392 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
2394 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
2395 gtk_widget_destroy (confirmation_dialog);
2396 if (!dialog_response) {
2397 g_object_unref (att_list);
2400 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
2402 for (iter = tny_list_create_iterator (att_list);
2403 !tny_iterator_is_done (iter);
2404 tny_iterator_next (iter)) {
2405 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2406 const gchar *att_id;
2407 tny_list_remove (priv->attachments, (GObject *) mime_part);
2409 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2411 if (tny_list_get_length (priv->attachments) == 0)
2412 gtk_widget_hide (priv->attachments_caption);
2413 att_id = tny_mime_part_get_content_id (mime_part);
2415 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2417 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2418 g_object_unref (mime_part);
2420 g_object_unref (iter);
2423 g_object_unref (att_list);
2425 /* if the last attachment has been removed, focus the Subject: field */
2426 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2427 gtk_widget_grab_focus (priv->subject_field);
2431 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2434 ModestMsgEditWindowPrivate *priv;
2435 GdkColor *new_color;
2436 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2438 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2439 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2442 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2444 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2446 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2448 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2453 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
2456 ModestMsgEditWindowPrivate *priv;
2457 gint new_size_index;
2458 ModestMsgEditWindow *window;
2461 window = MODEST_MSG_EDIT_WINDOW (userdata);
2462 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2463 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2465 if (gtk_check_menu_item_get_active (menu_item)) {
2467 WPTextBufferFormat format;
2469 memset (&format, 0, sizeof (format));
2470 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2472 label = gtk_bin_get_child (GTK_BIN (menu_item));
2474 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
2475 format.cs.font_size = TRUE;
2476 format.cs.text_position = TRUE;
2477 format.cs.font = TRUE;
2478 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
2479 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2481 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2482 GINT_TO_POINTER (wp_get_font_size_index (new_size_index, 12))))
2483 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2485 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2486 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
2487 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2493 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
2496 ModestMsgEditWindowPrivate *priv;
2497 gint new_font_index;
2498 ModestMsgEditWindow *window;
2501 window = MODEST_MSG_EDIT_WINDOW (userdata);
2502 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2503 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2505 if (gtk_check_menu_item_get_active (menu_item)) {
2508 label = gtk_bin_get_child (GTK_BIN (menu_item));
2510 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
2512 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2513 GINT_TO_POINTER(new_font_index)))
2514 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2516 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2517 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2518 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2524 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
2526 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
2527 ModestWindowPrivate *parent_priv;
2528 ModestWindowMgr *mgr;
2529 gboolean is_fullscreen;
2530 GtkAction *fs_toggle_action;
2533 mgr = modest_runtime_get_window_mgr ();
2534 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
2536 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
2538 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2539 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2540 if (is_fullscreen != active)
2541 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2549 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2552 ModestMsgEditWindowPrivate *priv = NULL;
2553 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2555 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2556 if (!priv->update_caption_visibility)
2559 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2561 gtk_widget_show (priv->cc_caption);
2563 gtk_widget_hide (priv->cc_caption);
2565 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2569 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2572 ModestMsgEditWindowPrivate *priv = NULL;
2573 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2575 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2576 if (!priv->update_caption_visibility)
2579 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2581 gtk_widget_show (priv->bcc_caption);
2583 gtk_widget_hide (priv->bcc_caption);
2585 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2589 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2590 ModestRecptEditor *editor)
2592 ModestMsgEditWindowPrivate *priv;
2594 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2595 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2596 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2598 if (editor == NULL) {
2599 GtkWidget *view_focus;
2600 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2602 /* This code should be kept in sync with ModestRecptEditor. The
2603 textview inside the recpt editor is the one that really gets the
2604 focus. As it's inside a scrolled window, and this one inside the
2605 hbox recpt editor inherits from, we'll need to go up in the
2606 hierarchy to know if the text view is part of the recpt editor
2607 or if it's a different text entry */
2609 if (gtk_widget_get_parent (view_focus)) {
2610 GtkWidget *first_parent;
2612 first_parent = gtk_widget_get_parent (view_focus);
2613 if (gtk_widget_get_parent (first_parent) &&
2614 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2615 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2620 editor = MODEST_RECPT_EDITOR (priv->to_field);
2624 modest_address_book_select_addresses (editor);
2629 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2631 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2633 modest_msg_edit_window_open_addressbook (window, NULL);
2637 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2638 gboolean show_toolbar)
2640 ModestWindowPrivate *parent_priv;
2641 const gchar *action_name;
2644 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2645 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2647 /* We can not just use the code of
2648 modest_msg_edit_window_setup_toolbar because it has a
2649 mixture of both initialization and creation code. */
2651 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2653 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2655 /* Update also the actions (to update the toggles in the
2656 menus), we have to do it manually because some other window
2657 of the same time could have changed it (remember that the
2658 toolbar fullscreen mode is shared by all the windows of the
2660 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
2661 action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarFullScreenMenu";
2663 action_name = "/MenuBar/ViewMenu/ShowToolbarMenu/ViewShowToolbarNormalScreenMenu";
2665 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
2666 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
2672 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2673 TnyHeaderFlags priority_flags)
2675 ModestMsgEditWindowPrivate *priv;
2676 ModestWindowPrivate *parent_priv;
2678 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2680 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2681 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2683 if (priv->priority_flags != priority_flags) {
2684 GtkAction *priority_action = NULL;
2686 priv->priority_flags = priority_flags;
2688 switch (priority_flags) {
2689 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2690 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2691 gtk_widget_show (priv->priority_icon);
2692 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2693 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2695 case TNY_HEADER_FLAG_LOW_PRIORITY:
2696 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2697 gtk_widget_show (priv->priority_icon);
2698 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2699 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2702 gtk_widget_hide (priv->priority_icon);
2703 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2704 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2707 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2708 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2713 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2716 ModestMsgEditWindowPrivate *priv;
2717 ModestWindowPrivate *parent_priv;
2718 gint current_format;
2720 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2722 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2723 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2725 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2726 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2728 if (current_format != file_format) {
2729 switch (file_format) {
2730 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2731 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2732 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
2734 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2738 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2739 response = gtk_dialog_run (GTK_DIALOG (dialog));
2740 gtk_widget_destroy (dialog);
2741 if (response == GTK_RESPONSE_OK) {
2742 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2744 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2745 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
2750 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2755 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2758 ModestMsgEditWindowPrivate *priv;
2759 WPTextBufferFormat oldfmt, fmt;
2760 gint old_position = 0;
2764 GdkColor *color = NULL;
2765 gboolean bold, bold_set, italic, italic_set;
2766 gboolean underline, underline_set;
2767 gboolean strikethrough, strikethrough_set;
2768 gboolean position_set;
2769 gboolean font_size_set, font_set, color_set;
2772 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2773 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2775 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2777 /* First we get the currently selected font information */
2778 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2780 switch (oldfmt.text_position) {
2781 case TEXT_POSITION_NORMAL:
2784 case TEXT_POSITION_SUPERSCRIPT:
2792 g_object_set (G_OBJECT (dialog),
2793 "bold", oldfmt.bold != FALSE,
2794 "bold-set", !oldfmt.cs.bold,
2795 "underline", oldfmt.underline != FALSE,
2796 "underline-set", !oldfmt.cs.underline,
2797 "italic", oldfmt.italic != FALSE,
2798 "italic-set", !oldfmt.cs.italic,
2799 "strikethrough", oldfmt.strikethrough != FALSE,
2800 "strikethrough-set", !oldfmt.cs.strikethrough,
2801 "color", &oldfmt.color,
2802 "color-set", !oldfmt.cs.color,
2803 "size", wp_font_size[oldfmt.font_size],
2804 "size-set", !oldfmt.cs.font_size,
2805 "position", old_position,
2806 "position-set", !oldfmt.cs.text_position,
2807 "family", wp_get_font_name (oldfmt.font),
2808 "family-set", !oldfmt.cs.font,
2811 gtk_widget_show_all (dialog);
2812 response = gtk_dialog_run (GTK_DIALOG (dialog));
2813 if (response == GTK_RESPONSE_OK) {
2815 g_object_get( dialog,
2817 "bold-set", &bold_set,
2818 "underline", &underline,
2819 "underline-set", &underline_set,
2821 "italic-set", &italic_set,
2822 "strikethrough", &strikethrough,
2823 "strikethrough-set", &strikethrough_set,
2825 "color-set", &color_set,
2827 "size-set", &font_size_set,
2828 "family", &font_name,
2829 "family-set", &font_set,
2830 "position", &position,
2831 "position-set", &position_set,
2836 if (response == GTK_RESPONSE_OK) {
2837 memset(&fmt, 0, sizeof(fmt));
2843 fmt.italic = italic;
2844 fmt.cs.italic = TRUE;
2846 if (underline_set) {
2847 fmt.underline = underline;
2848 fmt.cs.underline = TRUE;
2850 if (strikethrough_set) {
2851 fmt.strikethrough = strikethrough;
2852 fmt.cs.strikethrough = TRUE;
2857 ? TEXT_POSITION_NORMAL
2858 : ( ( position == 1 )
2859 ? TEXT_POSITION_SUPERSCRIPT
2860 : TEXT_POSITION_SUBSCRIPT );
2861 fmt.cs.text_position = TRUE;
2862 fmt.font_size = oldfmt.font_size;
2866 fmt.cs.color = TRUE;
2869 fmt.font = wp_get_font_index(font_name,
2874 if (font_size_set) {
2875 fmt.cs.font_size = TRUE;
2876 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
2878 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2879 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2881 gtk_widget_destroy (dialog);
2883 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2887 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2889 ModestMsgEditWindowPrivate *priv;
2891 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2892 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2894 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2896 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2897 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2902 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2904 ModestMsgEditWindowPrivate *priv;
2906 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2907 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2909 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2911 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2912 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2917 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2919 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2921 priv->can_undo = can_undo;
2925 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2927 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2929 priv->can_redo = can_redo;
2933 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
2935 ModestMsgEditWindowPrivate *priv;
2936 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2937 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2939 return priv->can_undo;
2943 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
2945 ModestMsgEditWindowPrivate *priv;
2946 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2947 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2949 return priv->can_redo;
2954 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2957 GtkTextIter match_start, match_end;
2959 if (image_id == NULL)
2962 gtk_text_buffer_get_start_iter (buffer, &iter);
2964 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2965 GSList *tags = gtk_text_iter_get_tags (&match_start);
2967 for (node = tags; node != NULL; node = g_slist_next (node)) {
2968 GtkTextTag *tag = (GtkTextTag *) node->data;
2969 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2970 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2971 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2973 offset = gtk_text_iter_get_offset (&match_start);
2974 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2975 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2979 gtk_text_iter_forward_char (&iter);
2984 message_is_empty (ModestMsgEditWindow *window)
2986 ModestMsgEditWindowPrivate *priv = NULL;
2988 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2989 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2991 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
2992 * so we can ignore markup.
2994 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
2997 count = gtk_text_buffer_get_char_count (buf);
3003 msg_body_focus (GtkWidget *focus,
3004 GdkEventFocus *event,
3008 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3009 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3010 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3015 recpt_field_changed (GtkTextBuffer *buffer,
3016 ModestMsgEditWindow *editor)
3018 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3019 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3023 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3025 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3026 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3030 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3033 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3034 GtkTextBuffer *buffer;
3036 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3037 gtk_text_buffer_set_modified (buffer, modified);
3038 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3039 gtk_text_buffer_set_modified (buffer, modified);
3040 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3041 gtk_text_buffer_set_modified (buffer, modified);
3042 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3046 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3048 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3049 const char *account_name;
3050 GtkTextBuffer *buffer;
3052 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3053 if (gtk_text_buffer_get_modified (buffer))
3055 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3056 if (gtk_text_buffer_get_modified (buffer))
3058 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3059 if (gtk_text_buffer_get_modified (buffer))
3061 if (gtk_text_buffer_get_modified (priv->text_buffer))
3063 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
3064 if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3075 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3077 ModestMsgEditWindowPrivate *priv = NULL;
3079 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3080 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3082 /* check if there's no recipient added */
3083 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3084 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3085 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3086 /* no recipient contents, then select contacts */
3087 modest_msg_edit_window_open_addressbook (window, NULL);
3091 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3092 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3095 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3096 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3099 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3100 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3104 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3105 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3106 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3113 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3114 ModestMsgEditWindow *window)
3116 modest_msg_edit_window_offer_attach_file (window);
3120 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3122 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3124 return priv->clipboard_text;
3128 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3130 ModestMsgEditWindow *window)
3132 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3133 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3135 if (!GTK_WIDGET_VISIBLE (window))
3138 text = gtk_clipboard_wait_for_text (selection_clipboard);
3140 if (priv->clipboard_text != NULL) {
3141 g_free (priv->clipboard_text);
3143 priv->clipboard_text = text;
3145 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3148 subject_field_move_cursor (GtkEntry *entry,
3149 GtkMovementStep step,
3154 if (!GTK_WIDGET_VISIBLE (window))
3157 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3161 update_window_title (ModestMsgEditWindow *window)
3163 ModestMsgEditWindowPrivate *priv = NULL;
3164 const gchar *subject;
3166 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3167 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3168 if (subject == NULL || subject[0] == '\0')
3169 subject = _("mail_va_new_email");
3171 gtk_window_set_title (GTK_WINDOW (window), subject);
3176 subject_field_changed (GtkEditable *editable,
3177 ModestMsgEditWindow *window)
3179 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3180 update_window_title (window);
3181 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3182 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3183 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3187 subject_field_insert_text (GtkEditable *editable,
3189 gint new_text_length,
3191 ModestMsgEditWindow *window)
3193 GString *result = g_string_new ("");
3195 gint result_len = 0;
3196 const gchar *entry_text = NULL;
3199 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3200 old_length = g_utf8_strlen (entry_text, -1);
3202 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3203 gunichar c = g_utf8_get_char_validated (current, 8);
3204 /* Invalid unichar, stop */
3210 result = g_string_append_unichar (result, c);
3214 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3215 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3218 /* Prevent endless recursion */
3219 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3220 g_signal_emit_by_name (editable, "insert-text",
3221 (gpointer) result->str, (gpointer) result->len,
3222 (gpointer) position, (gpointer) window);
3223 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3227 if (result_len + old_length > 1000) {
3228 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3229 dgettext("hildon-common-strings",
3230 "ckdg_ib_maximum_characters_reached"));
3233 g_string_free (result, TRUE);
3237 text_buffer_insert_text (GtkTextBuffer *buffer,
3240 gint new_text_length,
3241 ModestMsgEditWindow *window)
3243 GString *result = g_string_new ("");
3245 gint result_len = 0;
3246 gboolean changed = FALSE;
3248 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3249 gunichar c = g_utf8_get_char_validated (current, 8);
3250 /* Invalid unichar, stop */
3256 result = g_string_append_c (result, ' ');
3260 result = g_string_append_unichar (result, c);
3266 g_signal_stop_emission_by_name (G_OBJECT (buffer), "insert-text");
3267 g_signal_handlers_block_by_func(G_OBJECT(buffer), G_CALLBACK(text_buffer_insert_text), window);
3268 g_signal_emit_by_name (buffer, "insert-text",
3270 (gpointer) result->str, (gpointer) result->len,
3272 g_signal_handlers_unblock_by_func(G_OBJECT(buffer), G_CALLBACK(text_buffer_insert_text), window);
3275 g_string_free (result, TRUE);
3279 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3282 ModestMsgEditWindowPrivate *priv = NULL;
3284 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3285 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3287 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3290 gtk_widget_show_all (priv->find_toolbar);
3291 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3293 gtk_widget_hide_all (priv->find_toolbar);
3294 gtk_widget_grab_focus (priv->msg_body);
3300 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3302 GtkTextIter *match_start,
3303 GtkTextIter *match_end)
3305 GtkTextIter end_iter;
3306 gchar *str_casefold;
3309 gchar *range_casefold;
3312 gboolean result = FALSE;
3319 gtk_text_iter_forward_to_end (&end_iter);
3321 str_casefold = g_utf8_casefold (str, -1);
3322 str_chars_n = strlen (str);
3324 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3325 range_casefold = g_utf8_casefold (range_text, -1);
3326 range_chars_n = strlen (range_casefold);
3328 if (range_chars_n < str_chars_n) {
3329 g_free (str_casefold);
3330 g_free (range_text);
3331 g_free (range_casefold);
3335 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3336 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3337 if (!g_utf8_collate (range_subtext, str_casefold)) {
3338 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3340 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3341 match_start, match_end, NULL);
3342 g_free (found_text);
3344 g_free (range_subtext);
3348 g_free (str_casefold);
3349 g_free (range_text);
3350 g_free (range_casefold);
3357 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3358 ModestMsgEditWindow *window)
3360 gchar *current_search = NULL;
3361 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3363 GtkTextIter selection_start, selection_end;
3364 GtkTextIter match_start, match_end;
3365 gboolean continue_search = FALSE;
3367 if (message_is_empty (window)) {
3368 g_free (priv->last_search);
3369 priv->last_search = NULL;
3370 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3374 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3375 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3376 g_free (current_search);
3377 g_free (priv->last_search);
3378 priv->last_search = NULL;
3379 /* Information banner about empty search */
3380 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
3384 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3385 continue_search = TRUE;
3387 g_free (priv->last_search);
3388 priv->last_search = g_strdup (current_search);
3391 if (continue_search) {
3392 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3393 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3394 &match_start, &match_end);
3396 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
3398 GtkTextIter buffer_start;
3399 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3400 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3401 &match_start, &match_end);
3403 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
3406 /* Mark as selected the string found in search */
3408 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3409 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3410 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3412 g_free (priv->last_search);
3413 priv->last_search = NULL;
3415 g_free (current_search);
3419 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3420 ModestMsgEditWindow *window)
3422 GtkToggleAction *toggle;
3423 ModestWindowPrivate *parent_priv;
3424 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3426 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
3427 gtk_toggle_action_set_active (toggle, FALSE);
3431 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3433 ModestMsgEditWindowPrivate *priv;
3435 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3440 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3443 ModestMsgEditWindowPrivate *priv;
3445 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3451 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3454 ModestMsgEditWindowPrivate *priv;
3455 TnyHeader *header = NULL;
3457 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3458 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3460 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3461 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3463 if (priv->draft_msg != NULL) {
3464 g_object_unref (priv->draft_msg);
3467 if (draft != NULL) {
3468 g_object_ref (draft);
3469 header = tny_msg_get_header (draft);
3470 if (priv->msg_uid) {
3471 g_free (priv->msg_uid);
3472 priv->msg_uid = NULL;
3474 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3475 if (GTK_WIDGET_REALIZED (window))
3476 modest_window_mgr_register_window (mgr, MODEST_WINDOW (window));
3479 priv->draft_msg = draft;
3483 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3484 GtkTextIter *start, GtkTextIter *end,
3487 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3488 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3491 if (tag == NULL+13) return;
3492 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3493 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3494 replace_with_images (window, priv->images);
3499 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3502 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3504 g_return_if_fail (TNY_IS_MIME_PART (part));
3505 tny_list_prepend (priv->attachments, (GObject *) part);
3506 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3507 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3508 gtk_widget_show_all (priv->attachments_caption);
3509 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3513 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3515 ModestMsgEditWindowPrivate *priv;
3517 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3518 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3520 return priv->msg_uid;
3524 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3525 ModestMsgEditWindowWidgetType widget_type)
3527 ModestMsgEditWindowPrivate *priv;
3529 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3530 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3532 switch (widget_type) {
3533 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3534 return priv->msg_body;
3536 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3537 return priv->to_field;
3539 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3540 return priv->cc_field;
3542 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3543 return priv->bcc_field;
3545 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3546 return priv->subject_field;
3548 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3549 return priv->attachments_view;
3557 remove_tags (WPTextBuffer *buffer)
3559 GtkTextIter start, end;
3561 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3562 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3564 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3568 on_account_removed (TnyAccountStore *account_store,
3569 TnyAccount *account,
3572 /* Do nothing if it's a store account, because we use the
3573 transport to send the messages */
3574 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3575 const gchar *parent_acc = NULL;
3576 const gchar *our_acc = NULL;
3578 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3579 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3580 /* Close this window if I'm showing a message of the removed account */
3581 if (strcmp (parent_acc, our_acc) == 0)
3582 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3587 on_zoom_minus_plus_not_implemented (ModestWindow *window)
3589 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3591 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
3597 set_zoom_do_nothing (ModestWindow *window,
3603 get_zoom_do_nothing (ModestWindow *window)