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>
38 #include <tny-camel-mem-stream.h>
42 #include <modest-account-mgr.h>
43 #include <modest-account-mgr-helpers.h>
45 #include <widgets/modest-msg-edit-window.h>
46 #include <modest-selector-picker.h>
47 #include <widgets/modest-recpt-editor.h>
48 #include <widgets/modest-attachments-view.h>
50 #include <modest-runtime.h>
52 #include "modest-platform.h"
53 #include "modest-icon-names.h"
54 #include "modest-widget-memory.h"
55 #include "modest-window-priv.h"
56 #include "modest-mail-operation.h"
57 #include "modest-tny-platform-factory.h"
58 #include "modest-tny-msg.h"
59 #include "modest-tny-folder.h"
60 #include "modest-tny-account.h"
61 #include "modest-address-book.h"
62 #include "modest-text-utils.h"
63 #include <tny-simple-list.h>
64 #include <wptextview.h>
65 #include <wptextbuffer.h>
66 #include <hildon/hildon-pannable-area.h>
67 #include "modest-msg-edit-window-ui-dimming.h"
69 #include "modest-hildon-includes.h"
70 #ifdef MODEST_HAVE_HILDON0_WIDGETS
71 #include <hildon-widgets/hildon-color-chooser.h>
73 #include "widgets/modest-msg-edit-window-ui.h"
74 #ifdef MODEST_HAVE_HILDON0_WIDGETS
75 #include <libgnomevfs/gnome-vfs-mime-utils.h>
77 #include <libgnomevfs/gnome-vfs-mime.h>
79 #include <modest-utils.h>
80 #include "modest-maemo-utils.h"
81 #include <modest-ui-constants.h>
84 #define DEFAULT_FONT_SIZE 3
85 #define DEFAULT_FONT 2
86 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
87 #define DEFAULT_MAIN_VBOX_SPACING 6
88 #define SUBJECT_MAX_LENGTH 1000
89 #define IMAGE_MAX_WIDTH 560
90 #define DEFAULT_FONT_SCALE 1.5
92 static gboolean is_wp_text_buffer_started = FALSE;
94 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
95 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
96 static void modest_msg_edit_window_finalize (GObject *obj);
98 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
99 static void body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
100 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
102 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
103 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
104 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
105 static void text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
106 GtkTextIter *start, GtkTextIter *end,
108 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
109 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
110 static void subject_field_insert_text (GtkEditable *editable,
112 gint new_text_length,
114 ModestMsgEditWindow *window);
115 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
117 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
119 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
121 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
123 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
124 ModestRecptEditor *editor);
125 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
126 ModestMsgEditWindow *window);
128 /* ModestWindow methods implementation */
129 static void modest_msg_edit_window_disconnect_signals (ModestWindow *window);
130 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
131 gboolean show_toolbar);
132 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
134 ModestMsgEditWindow *window);
135 static void modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window);
136 static void subject_field_move_cursor (GtkEntry *entry,
137 GtkMovementStep step,
141 static void update_window_title (ModestMsgEditWindow *window);
144 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
145 ModestMsgEditWindow *window);
146 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
147 ModestMsgEditWindow *window);
148 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
150 GtkTextIter *match_start,
151 GtkTextIter *match_end);
153 static void remove_tags (WPTextBuffer *buffer);
155 static void on_account_removed (TnyAccountStore *account_store,
159 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
160 static void set_zoom_do_nothing (ModestWindow *window, gdouble zoom);
161 static gdouble get_zoom_do_nothing (ModestWindow *window);
163 static void init_window (ModestMsgEditWindow *obj);
165 gboolean scroll_drag_timeout (gpointer userdata);
166 static void correct_scroll (ModestMsgEditWindow *w);
167 static void correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused);
168 static void text_buffer_end_user_action (GtkTextBuffer *buffer,
169 ModestMsgEditWindow *userdata);
170 static void text_buffer_mark_set (GtkTextBuffer *buffer,
173 ModestMsgEditWindow *userdata);
174 static void on_message_settings (GtkAction *action,
175 ModestMsgEditWindow *window);
177 static void DEBUG_BUFFER (WPTextBuffer *buffer)
181 g_message ("BEGIN BUFFER OF SIZE %d", gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (buffer)));
183 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
184 while (!gtk_text_iter_is_end (&iter)) {
185 GString *output = g_string_new ("");
186 GSList *toggled_tags;
189 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
190 g_string_append_printf (output, "%d: CLOSED [ ", gtk_text_iter_get_offset (&iter));
191 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
192 GtkTextTag *tag = (GtkTextTag *) node->data;
194 g_object_get (G_OBJECT (tag), "name", &name, NULL);
195 output = g_string_append (output, name);
196 g_string_append (output, " ");
198 output = g_string_append (output, "] OPENED [ ");
199 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
200 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
201 GtkTextTag *tag = (GtkTextTag *) node->data;
203 g_object_get (G_OBJECT (tag), "name", &name, NULL);
204 output = g_string_append (output, name);
205 g_string_append (output, " ");
207 output = g_string_append (output, "]\n");
208 g_message ("%s", output->str);
209 g_string_free (output, TRUE);
210 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
212 g_message ("END BUFFER");
216 static const GtkActionEntry hildon2_msg_edit_action_entries [] = {
217 { "MessageSettings", NULL, N_("TODO: settings..."), NULL, NULL, G_CALLBACK (on_message_settings)},
221 /* static gboolean */
222 /* on_key_pressed (GtkWidget *self, */
223 /* GdkEventKey *event, */
224 /* gpointer user_data); */
226 /* list my signals */
233 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
234 struct _ModestMsgEditWindowPrivate {
237 GtkWidget *header_box;
239 ModestPairList *from_field_protos;
240 GtkWidget *from_field;
241 gchar *original_account_name;
245 GtkWidget *bcc_field;
246 GtkWidget *subject_field;
247 GtkWidget *attachments_view;
248 GtkWidget *priority_icon;
249 GtkWidget *add_attachment_button;
251 GtkWidget *cc_caption;
252 GtkWidget *bcc_caption;
253 gboolean update_caption_visibility;
254 GtkWidget *attachments_caption;
256 GtkTextBuffer *text_buffer;
258 GtkWidget *font_size_toolitem;
259 GtkWidget *font_face_toolitem;
260 GtkWidget *font_color_button;
261 GtkWidget *font_color_toolitem;
262 GSList *font_items_group;
263 GtkWidget *font_tool_button_label;
264 GSList *size_items_group;
265 GtkWidget *size_tool_button_label;
267 GtkWidget *find_toolbar;
270 GtkWidget *font_dialog;
273 guint scroll_drag_timeout_id;
277 TnyList *attachments;
282 TnyHeaderFlags priority_flags;
284 gboolean can_undo, can_redo;
285 gulong clipboard_change_handler_id;
286 gulong default_clipboard_change_handler_id;
287 gulong account_removed_handler_id;
288 guint clipboard_owner_idle;
289 gchar *clipboard_text;
298 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
299 MODEST_TYPE_MSG_EDIT_WINDOW, \
300 ModestMsgEditWindowPrivate))
302 static GtkWindowClass *parent_class = NULL;
304 /* uncomment the following if you have defined any signals */
305 /* static guint signals[LAST_SIGNAL] = {0}; */
308 modest_msg_edit_window_get_type (void)
310 static GType my_type = 0;
312 static const GTypeInfo my_info = {
313 sizeof(ModestMsgEditWindowClass),
314 NULL, /* base init */
315 NULL, /* base finalize */
316 (GClassInitFunc) modest_msg_edit_window_class_init,
317 NULL, /* class finalize */
318 NULL, /* class data */
319 sizeof(ModestMsgEditWindow),
321 (GInstanceInitFunc) modest_msg_edit_window_init,
324 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
325 "ModestMsgEditWindow",
333 save_state (ModestWindow *self)
335 modest_widget_memory_save (modest_runtime_get_conf(),
336 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
341 restore_settings (ModestMsgEditWindow *self)
343 ModestConf *conf = NULL;
345 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
347 conf = modest_runtime_get_conf ();
349 /* Dim at start clipboard actions */
350 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
351 gtk_action_set_sensitive (action, FALSE);
352 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
353 gtk_action_set_sensitive (action, FALSE);
354 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
355 gtk_action_set_sensitive (action, FALSE);
357 modest_widget_memory_restore (conf, G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
362 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
364 GObjectClass *gobject_class;
365 ModestWindowClass *modest_window_class;
366 gobject_class = (GObjectClass*) klass;
367 modest_window_class = (ModestWindowClass*) klass;
369 parent_class = g_type_class_peek_parent (klass);
370 gobject_class->finalize = modest_msg_edit_window_finalize;
372 modest_window_class->set_zoom_func = set_zoom_do_nothing;
373 modest_window_class->get_zoom_func = get_zoom_do_nothing;
374 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
375 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
376 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
377 modest_window_class->save_state_func = save_state;
378 modest_window_class->disconnect_signals_func = modest_msg_edit_window_disconnect_signals;
380 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
384 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
386 ModestMsgEditWindowPrivate *priv;
387 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
389 priv->msg_body = NULL;
391 priv->from_field = NULL;
392 priv->to_field = NULL;
393 priv->cc_field = NULL;
394 priv->bcc_field = NULL;
395 priv->subject_field = NULL;
396 priv->attachments = TNY_LIST (tny_simple_list_new ());
397 priv->images = TNY_LIST (tny_simple_list_new ());
398 priv->images_size = 0;
399 priv->images_count = 0;
402 priv->cc_caption = NULL;
403 priv->bcc_caption = NULL;
404 priv->update_caption_visibility = FALSE;
406 priv->priority_flags = 0;
408 priv->find_toolbar = NULL;
409 priv->last_search = NULL;
411 priv->draft_msg = NULL;
412 priv->outbox_msg = NULL;
413 priv->msg_uid = NULL;
415 priv->can_undo = FALSE;
416 priv->can_redo = FALSE;
417 priv->clipboard_change_handler_id = 0;
418 priv->default_clipboard_change_handler_id = 0;
419 priv->account_removed_handler_id = 0;
420 priv->clipboard_owner_idle = 0;
421 priv->clipboard_text = NULL;
424 priv->scroll_drag_timeout_id = 0;
425 priv->last_upper = 0.0;
427 priv->font_dialog = NULL;
429 if (!is_wp_text_buffer_started) {
430 is_wp_text_buffer_started = TRUE;
431 wp_text_buffer_library_init ();
436 hildon_program_add_window (hildon_program_get_instance(),
442 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
444 static ModestPairList*
445 get_transports (void)
447 GSList *transports = NULL;
449 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
450 GSList *accounts = modest_account_mgr_account_names (account_mgr,
451 TRUE /* only enabled accounts. */);
453 GSList *cursor = accounts;
455 gchar *account_name = cursor->data;
456 gchar *from_string = NULL;
458 from_string = modest_account_mgr_get_from_string (account_mgr,
462 if (from_string && account_name) {
463 gchar *name = account_name;
464 ModestPair *pair = modest_pair_new ((gpointer) name,
465 (gpointer) from_string , TRUE);
466 transports = g_slist_prepend (transports, pair);
469 cursor = cursor->next;
471 g_slist_free (accounts); /* only free the accounts, not the elements,
472 * because they are used in the pairlist */
476 static void window_focus (GtkWindow *window,
480 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
484 scroll_drag_timeout (gpointer userdata)
486 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
487 ModestMsgEditWindowPrivate *priv;
489 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
491 correct_scroll_without_drag_check (win, TRUE);
493 priv->scroll_drag_timeout_id = 0;
499 correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused)
501 ModestMsgEditWindowPrivate *priv;
504 GdkRectangle rectangle;
508 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
510 if (only_if_focused && !gtk_widget_is_focus (priv->msg_body))
513 insert = gtk_text_buffer_get_insert (priv->text_buffer);
514 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
516 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
517 offset = priv->msg_body->allocation.y;
519 new_value = (offset + rectangle.y);
521 hildon_pannable_area_jump_to (HILDON_PANNABLE_AREA (priv->pannable), -1, new_value);
525 correct_scroll (ModestMsgEditWindow *w)
527 ModestMsgEditWindowPrivate *priv;
529 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
530 if (gtk_grab_get_current () == priv->msg_body) {
531 if (priv->scroll_drag_timeout_id == 0) {
532 priv->scroll_drag_timeout_id = g_timeout_add (500, (GSourceFunc) scroll_drag_timeout,
538 correct_scroll_without_drag_check (w, TRUE);
542 text_buffer_end_user_action (GtkTextBuffer *buffer,
543 ModestMsgEditWindow *userdata)
546 correct_scroll (userdata);
550 text_buffer_mark_set (GtkTextBuffer *buffer,
553 ModestMsgEditWindow *userdata)
555 gtk_text_buffer_begin_user_action (buffer);
556 gtk_text_buffer_end_user_action (buffer);
560 cut_clipboard_check (GtkTextView *text_view,
563 GtkTextBuffer *buffer;
565 buffer = gtk_text_view_get_buffer (text_view);
566 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
567 g_signal_stop_emission_by_name ((gpointer )text_view, "cut-clipboard");
572 copy_clipboard_check (GtkTextView *text_view,
575 GtkTextBuffer *buffer;
577 buffer = gtk_text_view_get_buffer (text_view);
578 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
579 g_signal_stop_emission_by_name ((gpointer )text_view, "copy-clipboard");
584 attachment_deleted (ModestAttachmentsView *attachments_view,
587 modest_msg_edit_window_remove_attachments (MODEST_MSG_EDIT_WINDOW (user_data),
592 connect_signals (ModestMsgEditWindow *obj)
594 ModestMsgEditWindowPrivate *priv;
596 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
598 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
599 G_CALLBACK (text_buffer_refresh_attributes), obj);
600 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
601 G_CALLBACK (text_buffer_can_undo), obj);
602 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
603 G_CALLBACK (text_buffer_can_redo), obj);
604 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
605 G_CALLBACK (body_changed), obj);
606 g_signal_connect (G_OBJECT (priv->text_buffer), "modified-changed",
607 G_CALLBACK (body_changed), obj);
608 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
609 G_CALLBACK (text_buffer_end_user_action), obj);
610 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
611 G_CALLBACK (text_buffer_mark_set), obj);
612 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
613 G_CALLBACK (text_buffer_apply_tag), obj);
614 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
615 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
616 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
617 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
618 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
619 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
621 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
622 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
624 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
625 G_CALLBACK (msg_body_focus), obj);
626 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
627 G_CALLBACK (msg_body_focus), obj);
628 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
629 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
630 "changed", G_CALLBACK (recpt_field_changed), obj);
631 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
632 "changed", G_CALLBACK (recpt_field_changed), obj);
633 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
634 "changed", G_CALLBACK (recpt_field_changed), obj);
635 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
636 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
637 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
639 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
640 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
642 priv->clipboard_change_handler_id =
643 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
644 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
645 priv->default_clipboard_change_handler_id =
646 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
647 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
649 g_signal_connect (G_OBJECT (priv->msg_body), "cut-clipboard", G_CALLBACK (cut_clipboard_check), NULL);
650 g_signal_connect (G_OBJECT (priv->msg_body), "copy-clipboard", G_CALLBACK (copy_clipboard_check), NULL);
651 g_signal_connect (G_OBJECT (priv->attachments_view), "delete", G_CALLBACK (attachment_deleted), obj);
655 init_wp_text_view_style ()
657 static gboolean initialized = FALSE;
660 gtk_rc_parse_string ("class \"WPTextView\" style \"fremantle-textview\"");
666 init_window (ModestMsgEditWindow *obj)
668 GtkWidget *to_caption, *subject_caption;
669 GtkWidget *main_vbox;
670 ModestMsgEditWindowPrivate *priv;
671 GtkActionGroup *action_group;
672 ModestWindowPrivate *parent_priv;
673 GdkPixbuf *window_icon = NULL;
674 GError *error = NULL;
676 GtkSizeGroup *title_size_group;
677 GtkSizeGroup *value_size_group;
678 GtkWidget *subject_box;
679 GtkWidget *attachment_icon;
680 GtkWidget *window_box;
681 #if (GTK_MINOR_VERSION >= 10)
682 GdkAtom deserialize_type;
685 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
686 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
688 parent_priv->ui_manager = gtk_ui_manager_new();
689 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
690 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
692 /* Add common actions */
693 gtk_action_group_add_actions (action_group,
694 modest_msg_edit_action_entries,
695 G_N_ELEMENTS (modest_msg_edit_action_entries),
697 gtk_action_group_add_actions (action_group,
698 hildon2_msg_edit_action_entries,
699 G_N_ELEMENTS (hildon2_msg_edit_action_entries),
701 gtk_action_group_add_toggle_actions (action_group,
702 modest_msg_edit_toggle_action_entries,
703 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
705 gtk_action_group_add_radio_actions (action_group,
706 modest_msg_edit_alignment_radio_action_entries,
707 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
709 G_CALLBACK (modest_ui_actions_on_change_justify),
711 gtk_action_group_add_radio_actions (action_group,
712 modest_msg_edit_priority_action_entries,
713 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
715 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
717 gtk_action_group_add_radio_actions (action_group,
718 modest_msg_edit_file_format_action_entries,
719 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
720 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
721 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
723 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
724 g_object_unref (action_group);
726 /* Load the UI definition */
727 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
730 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
731 g_clear_error (&error);
734 /* Add accelerators */
735 gtk_window_add_accel_group (GTK_WINDOW (obj),
736 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
738 parent_priv->menubar = NULL;
740 title_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
741 value_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
743 /* Note: This ModestPairList* must exist for as long as the picker
744 * that uses it, because the ModestSelectorPicker uses the ID opaquely,
745 * so it can't know how to manage its memory. */
746 priv->from_field = modest_selector_picker_new (MODEST_EDITABLE_SIZE,
747 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
749 modest_maemo_utils_set_hbutton_layout (title_size_group, value_size_group,
750 _("mail_va_from"), priv->from_field);
752 priv->to_field = modest_recpt_editor_new ();
753 priv->cc_field = modest_recpt_editor_new ();
754 priv->bcc_field = modest_recpt_editor_new ();
755 subject_box = gtk_hbox_new (FALSE, 0);
756 priv->priority_icon = gtk_image_new ();
757 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
758 priv->subject_field = hildon_entry_new (MODEST_EDITABLE_SIZE);
759 gtk_entry_set_max_length (GTK_ENTRY (priv->subject_field) ,SUBJECT_MAX_LENGTH);
760 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
761 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
762 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
763 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
764 priv->add_attachment_button = gtk_button_new ();
765 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
766 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
767 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
768 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 0.5);
769 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, HILDON_ICON_SIZE_FINGER);
770 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
771 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
772 priv->attachments_view = modest_attachments_view_new (NULL);
774 priv->header_box = gtk_vbox_new (FALSE, 0);
776 to_caption = modest_maemo_utils_create_captioned_with_size_type
777 (title_size_group, value_size_group,
778 _("mail_va_to"), priv->to_field,
779 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
780 priv->cc_caption = modest_maemo_utils_create_captioned_with_size_type
781 (title_size_group, value_size_group,
782 _("mail_va_cc"), priv->cc_field,
783 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
784 priv->bcc_caption = modest_maemo_utils_create_captioned_with_size_type
785 (title_size_group, value_size_group,
786 _("mail_va_hotfix1"), priv->bcc_field,
787 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
788 subject_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
789 _("mail_va_subject"), subject_box);
790 priv->attachments_caption = modest_maemo_utils_create_captioned_with_size_type (title_size_group, value_size_group,
791 _("mail_va_attachment"),
792 priv->attachments_view,
793 HILDON_SIZE_AUTO_WIDTH |
794 HILDON_SIZE_AUTO_HEIGHT);
795 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), value_size_group); */
796 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), value_size_group); */
797 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), value_size_group); */
798 g_object_unref (title_size_group);
799 g_object_unref (value_size_group);
801 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->from_field, FALSE, FALSE, 0);
802 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
803 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
804 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
805 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
806 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
807 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
809 init_wp_text_view_style ();
811 priv->msg_body = wp_text_view_new ();
814 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
815 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
816 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
817 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
818 #if (GTK_MINOR_VERSION >= 10)
819 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), NULL);
820 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
822 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
823 deserialize_type, TRUE);
825 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
827 priv->find_toolbar = hildon_find_toolbar_new (NULL);
828 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
830 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
832 priv->pannable = hildon_pannable_area_new ();
834 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
836 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
837 priv->frame = gtk_frame_new (NULL);
838 gtk_box_pack_start (GTK_BOX(main_vbox), priv->frame, TRUE, TRUE, 0);
840 hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA (priv->pannable), main_vbox);
841 gtk_widget_show_all (GTK_WIDGET(priv->pannable));
843 window_box = gtk_vbox_new (FALSE, 0);
844 gtk_container_add (GTK_CONTAINER(obj), window_box);
846 gtk_box_pack_start (GTK_BOX (window_box), priv->pannable, TRUE, TRUE, 0);
848 gtk_container_add (GTK_CONTAINER (priv->frame), priv->msg_body);
850 /* Set window icon */
851 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
853 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
854 g_object_unref (window_icon);
859 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
861 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
863 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
864 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
865 priv->clipboard_change_handler_id))
866 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
867 priv->clipboard_change_handler_id);
868 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
869 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
870 priv->default_clipboard_change_handler_id))
871 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
872 priv->default_clipboard_change_handler_id);
874 if (priv->account_removed_handler_id &&
875 g_signal_handler_is_connected (modest_runtime_get_account_store (),
876 priv->account_removed_handler_id))
877 g_signal_handler_disconnect(modest_runtime_get_account_store (),
878 priv->account_removed_handler_id);
882 modest_msg_edit_window_finalize (GObject *obj)
884 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
886 /* Sanity check: shouldn't be needed, the window mgr should
887 call this function before */
888 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
890 if (priv->font_dialog != NULL) {
891 gtk_dialog_response (GTK_DIALOG (priv->font_dialog), GTK_RESPONSE_NONE);
894 if (priv->clipboard_text != NULL) {
895 g_free (priv->clipboard_text);
896 priv->clipboard_text = NULL;
899 if (priv->draft_msg != NULL) {
900 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
901 if (TNY_IS_HEADER (header)) {
902 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
903 modest_window_mgr_unregister_header (mgr, header);
905 g_object_unref (priv->draft_msg);
906 priv->draft_msg = NULL;
908 if (priv->outbox_msg != NULL) {
909 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
910 if (TNY_IS_HEADER (header)) {
911 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
912 modest_window_mgr_unregister_header (mgr, header);
914 g_object_unref (priv->outbox_msg);
915 priv->outbox_msg = NULL;
917 if (priv->scroll_drag_timeout_id > 0) {
918 g_source_remove (priv->scroll_drag_timeout_id);
919 priv->scroll_drag_timeout_id = 0;
921 if (priv->clipboard_owner_idle > 0) {
922 g_source_remove (priv->clipboard_owner_idle);
923 priv->clipboard_owner_idle = 0;
925 if (priv->original_account_name)
926 g_free (priv->original_account_name);
927 g_free (priv->msg_uid);
928 g_free (priv->last_search);
929 g_slist_free (priv->font_items_group);
930 g_slist_free (priv->size_items_group);
931 g_object_unref (priv->attachments);
932 g_object_unref (priv->images);
934 /* This had to stay alive for as long as the picker that used it: */
935 modest_pair_list_free (priv->from_field_protos);
937 G_OBJECT_CLASS(parent_class)->finalize (obj);
941 pixbuf_from_stream (TnyStream *stream, const gchar *mime_type, guint64 *stream_size)
943 GdkPixbufLoader *loader;
949 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
951 if (loader == NULL) {
957 tny_stream_reset (TNY_STREAM (stream));
958 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
959 GError *error = NULL;
960 unsigned char read_buffer[128];
962 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
964 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, &error)) {
966 g_error_free (error);
971 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
973 g_object_ref (pixbuf);
974 gdk_pixbuf_loader_close (loader, NULL);
975 g_object_unref (loader);
980 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
981 GdkPixbuf *new_pixbuf;
983 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
984 gdk_pixbuf_get_width (pixbuf);
985 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
986 g_object_unref (pixbuf);
997 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
999 ModestMsgEditWindowPrivate *priv;
1002 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1004 for (iter = tny_list_create_iterator (attachments);
1005 !tny_iterator_is_done (iter);
1006 tny_iterator_next (iter)) {
1007 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1008 const gchar *cid = tny_mime_part_get_content_id (part);
1009 const gchar *mime_type = tny_mime_part_get_content_type (part);
1010 if ((cid != NULL)&&(mime_type != NULL)) {
1011 guint64 stream_size;
1012 TnyStream *stream = tny_mime_part_get_decoded_stream (part);
1013 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
1016 g_object_unref (stream);
1018 if (pixbuf != NULL) {
1019 priv->images_count ++;
1020 priv->images_size += stream_size;
1021 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1022 g_object_unref (pixbuf);
1025 g_object_unref (part);
1027 g_object_unref (iter);
1031 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1033 TnyMimePart *parent = NULL;
1034 const gchar *content_type = NULL;
1035 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1037 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1039 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1040 parent = g_object_ref (msg);
1041 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1042 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1045 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1046 iter = tny_list_create_iterator (parts);
1047 while (!tny_iterator_is_done (iter)) {
1049 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1050 content_type = tny_mime_part_get_content_type (part);
1051 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1055 g_object_unref (part);
1057 tny_iterator_next (iter);
1059 g_object_unref (iter);
1060 g_object_unref (parts);
1063 if (parent != NULL) {
1064 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1067 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1068 iter = tny_list_create_iterator (parts);
1069 while (!tny_iterator_is_done (iter)) {
1071 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1072 content_type = tny_mime_part_get_content_type (part);
1073 if (content_type && g_str_has_prefix (content_type, "image/")) {
1074 tny_list_prepend (priv->images, (GObject *) part);
1076 g_object_unref (part);
1077 tny_iterator_next (iter);
1079 g_object_unref (iter);
1080 g_object_unref (parts);
1081 g_object_unref (parent);
1086 update_next_cid (ModestMsgEditWindow *self, TnyList *attachments)
1089 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1091 for (iter = tny_list_create_iterator (attachments) ;
1092 !tny_iterator_is_done (iter);
1093 tny_iterator_next (iter)) {
1094 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1095 const gchar *cid = tny_mime_part_get_content_id (part);
1097 char *invalid = NULL;
1098 gint int_cid = strtol (cid, &invalid, 10);
1099 if ((invalid != NULL) && (*invalid == '\0') && (int_cid >= priv->next_cid)) {
1100 priv->next_cid = int_cid + 1;
1103 g_object_unref (part);
1105 g_object_unref (iter);
1109 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1112 gchar *to, *cc, *bcc, *subject;
1114 ModestMsgEditWindowPrivate *priv;
1115 ModestWindowPrivate *parent_priv;
1117 TnyHeaderFlags priority_flags;
1118 TnyFolder *msg_folder;
1119 gboolean is_html = FALSE;
1121 gboolean field_view_set;
1123 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1124 g_return_if_fail (TNY_IS_MSG (msg));
1126 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1127 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1129 header = tny_msg_get_header (msg);
1130 to = tny_header_dup_to (header);
1131 cc = tny_header_dup_cc (header);
1132 bcc = tny_header_dup_bcc (header);
1133 subject = tny_header_dup_subject (header);
1134 priority_flags = tny_header_get_priority (header);
1137 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1139 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
1140 field_view_set = TRUE;
1142 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1143 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1144 gtk_widget_show (priv->cc_caption);
1145 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1146 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1147 gtk_widget_hide (priv->cc_caption);
1148 field_view_set = FALSE;
1151 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), field_view_set);
1153 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
1154 field_view_set = TRUE;
1156 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1157 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1158 gtk_widget_show (priv->bcc_caption);
1159 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1160 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1161 gtk_widget_hide (priv->bcc_caption);
1162 field_view_set = FALSE;
1165 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), field_view_set);
1169 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1170 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1173 update_window_title (self);
1175 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1176 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1178 if ((body == NULL)||(body[0] == '\0')) {
1180 body = modest_text_utils_convert_to_html ("");
1183 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1184 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1187 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1190 /* Add attachments to the view */
1191 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1192 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1193 if (tny_list_get_length (priv->attachments) == 0) {
1194 gtk_widget_hide (priv->attachments_caption);
1196 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1197 gtk_widget_show_all (priv->attachments_caption);
1199 get_related_images (self, msg);
1200 update_next_cid (self, priv->attachments);
1201 update_next_cid (self, priv->images);
1202 replace_with_images (self, priv->images);
1204 if (preserve_is_rich && !is_html) {
1205 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1206 /* Get the default format required from configuration */
1207 } else if (!preserve_is_rich && !modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1208 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1211 /* Set the default focus depending on having already a To: field or not */
1212 if ((!to)||(*to == '\0')) {
1213 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1215 gtk_widget_grab_focus (priv->msg_body);
1218 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1220 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1221 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1223 modest_msg_edit_window_set_modified (self, FALSE);
1225 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1226 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1227 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1228 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1230 if (priv->msg_uid) {
1231 g_free (priv->msg_uid);
1232 priv->msg_uid = NULL;
1235 /* we should set a reference to the incoming message if it is a draft */
1236 msg_folder = tny_msg_get_folder (msg);
1238 if (modest_tny_folder_is_local_folder (msg_folder)) {
1239 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1240 if (type == TNY_FOLDER_TYPE_INVALID)
1241 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1243 if (type == TNY_FOLDER_TYPE_DRAFTS)
1244 priv->draft_msg = g_object_ref(msg);
1245 if (type == TNY_FOLDER_TYPE_OUTBOX)
1246 priv->outbox_msg = g_object_ref(msg);
1247 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1249 g_object_unref (msg_folder);
1259 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
1262 GList *item_children, *node;
1263 GtkWidget *bin_child;
1265 bin_child = gtk_bin_get_child (GTK_BIN(item));
1267 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
1269 for (node = item_children; node != NULL; node = g_list_next (node)) {
1270 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
1271 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
1274 g_list_free (item_children);
1278 menu_tool_button_dont_expand (GtkMenuToolButton *item)
1281 GList *item_children, *node;
1283 box = gtk_bin_get_child (GTK_BIN (item));
1284 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
1285 item_children = gtk_container_get_children (GTK_CONTAINER (box));
1287 for (node = item_children; node != NULL; node = g_list_next (node)) {
1288 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
1289 if (GTK_IS_TOGGLE_BUTTON (node->data))
1290 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
1291 else if (GTK_IS_BUTTON (node->data))
1292 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
1294 g_list_free (item_children);
1299 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1301 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1302 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1303 GtkWidget *placeholder;
1304 GtkWidget *tool_item;
1309 GtkWidget *sizes_menu;
1310 GtkWidget *fonts_menu;
1311 GSList *radio_group = NULL;
1312 GSList *node = NULL;
1316 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1317 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1319 /* Font color placeholder */
1320 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1321 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1324 priv->font_color_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1325 priv->font_color_button = hildon_color_button_new ();
1326 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
1327 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1328 gtk_container_add (GTK_CONTAINER (priv->font_color_toolitem), priv->font_color_button);
1329 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1330 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1331 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->font_color_toolitem), insert_index);
1332 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1334 G_CALLBACK (modest_msg_edit_window_color_button_change),
1337 /* Font size and face placeholder */
1338 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1339 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1341 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1342 priv->size_tool_button_label = gtk_label_new (NULL);
1343 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1344 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1345 size_text,"</span>", NULL);
1346 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1348 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
1349 sizes_menu = gtk_menu_new ();
1350 priv->size_items_group = NULL;
1352 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1353 GtkWidget *size_menu_item;
1355 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1356 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
1357 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
1358 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
1359 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
1360 gtk_widget_show (size_menu_item);
1362 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
1366 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1367 GtkWidget *item = (GtkWidget *) node->data;
1368 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
1372 priv->size_items_group = g_slist_reverse (priv->size_items_group);
1373 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
1374 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1375 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1376 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1377 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1378 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1379 priv->font_size_toolitem = tool_item;
1382 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
1383 priv->font_tool_button_label = gtk_label_new (NULL);
1384 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1385 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1387 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
1388 fonts_menu = gtk_menu_new ();
1389 priv->font_items_group = NULL;
1391 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1392 GtkWidget *font_menu_item;
1393 GtkWidget *child_label;
1395 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
1396 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
1397 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
1398 wp_get_font_name (font_index), "</span>", NULL);
1399 gtk_label_set_markup (GTK_LABEL (child_label), markup);
1402 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
1403 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
1404 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
1405 gtk_widget_show (font_menu_item);
1407 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
1410 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
1411 GtkWidget *item = (GtkWidget *) node->data;
1412 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
1415 priv->font_items_group = g_slist_reverse (priv->font_items_group);
1416 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
1417 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
1418 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1419 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1420 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1421 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
1422 priv->font_face_toolitem = tool_item;
1424 /* Set expand and homogeneous for remaining items */
1425 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1426 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1427 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1428 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1429 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1430 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1431 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1432 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1433 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1435 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1436 will not show the tool items added to the placeholders) */
1437 gtk_widget_show_all (parent_priv->toolbar);
1439 /* Set the no show all *after* showing all items. We do not
1440 want the toolbar to be shown with a show all because it
1441 could go agains the gconf setting regarding showing or not
1442 the toolbar of the editor window */
1443 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1449 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, gboolean preserve_is_rich)
1452 ModestWindowPrivate *parent_priv;
1453 ModestMsgEditWindowPrivate *priv;
1454 ModestDimmingRulesGroup *menu_rules_group = NULL;
1455 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1456 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1457 ModestWindowMgr *mgr = NULL;
1459 g_return_val_if_fail (msg, NULL);
1460 g_return_val_if_fail (account_name, NULL);
1462 mgr = modest_runtime_get_window_mgr ();
1464 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1466 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1467 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1469 /* Menubar. Update the state of some toggles */
1470 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1471 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
1472 priv->from_field_protos = get_transports ();
1473 modest_selector_picker_set_pair_list (MODEST_SELECTOR_PICKER (priv->from_field), priv->from_field_protos);
1474 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1475 hildon_button_set_title (HILDON_BUTTON (priv->from_field),
1477 hildon_button_set_value (HILDON_BUTTON (priv->from_field),
1478 hildon_touch_selector_get_current_text
1479 (HILDON_TOUCH_SELECTOR (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (priv->from_field)))));
1480 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1481 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1484 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1486 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1488 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1490 priv->original_account_name = (account_name) ? g_strdup (account_name) : NULL;
1492 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new ();
1493 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1494 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1495 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1496 /* Add common dimming rules */
1497 modest_dimming_rules_group_add_rules (menu_rules_group,
1498 modest_msg_edit_window_menu_dimming_entries,
1499 G_N_ELEMENTS (modest_msg_edit_window_menu_dimming_entries),
1500 MODEST_WINDOW (obj));
1501 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1502 modest_msg_edit_window_toolbar_dimming_entries,
1503 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1504 MODEST_WINDOW (obj));
1505 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_toolitem,
1506 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1507 MODEST_WINDOW (obj));
1508 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1509 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1510 MODEST_WINDOW (obj));
1511 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1512 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1513 MODEST_WINDOW (obj));
1514 /* Insert dimming rules group for this window */
1515 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1516 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1517 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1518 /* Checks the dimming rules */
1519 g_object_unref (menu_rules_group);
1520 g_object_unref (toolbar_rules_group);
1521 g_object_unref (clipboard_rules_group);
1522 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1524 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1526 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1527 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1528 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1529 priv->update_caption_visibility = TRUE;
1531 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1533 /* Track account-removed signal, this window should be closed
1534 in the case we're creating a mail associated to the account
1536 priv->account_removed_handler_id =
1537 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1539 G_CALLBACK(on_account_removed),
1542 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (MODEST_MSG_EDIT_WINDOW (obj));
1544 return (ModestWindow*) obj;
1548 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1550 GString **string_buffer = (GString **) user_data;
1552 *string_buffer = g_string_append (*string_buffer, buffer);
1558 * @result: A new string which should be freed with g_free().
1561 get_formatted_data (ModestMsgEditWindow *edit_window)
1563 ModestMsgEditWindowPrivate *priv;
1564 GString *string_buffer = g_string_new ("");
1566 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1568 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1570 modest_text_utils_hyperlinkify (string_buffer);
1572 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1574 return g_string_free (string_buffer, FALSE);
1579 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1582 const gchar *account_name;
1583 ModestMsgEditWindowPrivate *priv;
1584 TnyIterator *att_iter;
1586 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1588 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1590 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1591 g_return_val_if_fail (account_name, NULL);
1594 /* don't free these (except from) */
1595 data = g_slice_new0 (MsgData);
1596 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1598 data->account_name = g_strdup (account_name);
1599 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1600 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1601 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1602 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1603 if (priv->draft_msg) {
1604 data->draft_msg = g_object_ref (priv->draft_msg);
1605 } else if (priv->outbox_msg) {
1606 data->draft_msg = g_object_ref (priv->outbox_msg);
1608 data->draft_msg = NULL;
1611 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1613 gtk_text_buffer_get_bounds (buf, &b, &e);
1614 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1616 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1617 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1619 data->html_body = NULL;
1621 /* deep-copy the data */
1622 att_iter = tny_list_create_iterator (priv->attachments);
1623 data->attachments = NULL;
1624 while (!tny_iterator_is_done (att_iter)) {
1625 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1626 if (!(TNY_IS_MIME_PART(part))) {
1627 g_warning ("strange data in attachment list");
1628 g_object_unref (part);
1629 tny_iterator_next (att_iter);
1632 data->attachments = g_list_append (data->attachments,
1634 tny_iterator_next (att_iter);
1636 g_object_unref (att_iter);
1638 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1639 att_iter = tny_list_create_iterator (priv->images);
1640 data->images = NULL;
1641 while (!tny_iterator_is_done (att_iter)) {
1642 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1644 if (!(TNY_IS_MIME_PART(part))) {
1645 g_warning ("strange data in attachment list");
1646 g_object_unref (part);
1647 tny_iterator_next (att_iter);
1650 cid = tny_mime_part_get_content_id (part);
1652 gchar *image_tag_id;
1653 GtkTextTag *image_tag;
1655 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1656 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1657 g_free (image_tag_id);
1659 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1661 ((gtk_text_iter_has_tag (&iter, image_tag))||
1662 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1663 data->images = g_list_append (data->images,
1664 g_object_ref (part));
1666 g_object_unref (part);
1667 tny_iterator_next (att_iter);
1669 g_object_unref (att_iter);
1671 data->priority_flags = priv->priority_flags;
1678 unref_gobject (GObject *obj, gpointer data)
1680 if (!G_IS_OBJECT(obj))
1682 g_object_unref (obj);
1686 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1689 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1697 g_free (data->from);
1698 g_free (data->subject);
1699 g_free (data->plain_body);
1700 g_free (data->html_body);
1701 g_free (data->account_name);
1703 if (data->draft_msg != NULL) {
1704 g_object_unref (data->draft_msg);
1705 data->draft_msg = NULL;
1708 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1709 g_list_free (data->attachments);
1710 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1711 g_list_free (data->images);
1713 g_slice_free (MsgData, data);
1717 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1719 guint64 *parts_size)
1721 ModestMsgEditWindowPrivate *priv;
1723 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1725 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1727 /* TODO: add images */
1728 *parts_size += priv->images_size;
1729 *parts_count += priv->images_count;
1734 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1737 ModestMsgEditWindowPrivate *priv = NULL;
1738 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1740 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1742 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1744 return MODEST_MSG_EDIT_FORMAT_HTML;
1746 return MODEST_MSG_EDIT_FORMAT_TEXT;
1750 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1751 ModestMsgEditFormat format)
1753 ModestMsgEditWindowPrivate *priv;
1755 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1756 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1759 case MODEST_MSG_EDIT_FORMAT_HTML:
1760 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1762 case MODEST_MSG_EDIT_FORMAT_TEXT:
1763 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1766 g_return_if_reached ();
1770 ModestMsgEditFormatState *
1771 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1773 ModestMsgEditFormatState *format_state = NULL;
1774 ModestMsgEditWindowPrivate *priv;
1775 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1777 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1778 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1780 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1782 format_state = g_new0 (ModestMsgEditFormatState, 1);
1783 format_state->bold = buffer_format->bold&0x1;
1784 format_state->italics = buffer_format->italic&0x1;
1785 format_state->bullet = buffer_format->bullet&0x1;
1786 format_state->color = buffer_format->color;
1787 format_state->font_size = buffer_format->font_size;
1788 format_state->font_family = wp_get_font_name (buffer_format->font);
1789 format_state->justification = buffer_format->justification;
1790 g_free (buffer_format);
1792 return format_state;
1797 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1798 const ModestMsgEditFormatState *format_state)
1800 ModestMsgEditWindowPrivate *priv;
1801 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1802 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1803 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1804 g_return_if_fail (format_state != NULL);
1806 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1807 gtk_widget_grab_focus (priv->msg_body);
1808 buffer_format->bold = (format_state->bold != FALSE);
1809 buffer_format->italic = (format_state->italics != FALSE);
1810 buffer_format->color = format_state->color;
1811 buffer_format->font_size = format_state->font_size;
1812 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1813 buffer_format->justification = format_state->justification;
1814 buffer_format->bullet = format_state->bullet;
1816 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1818 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1819 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1820 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1821 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1822 buffer_format->cs.font = (buffer_format->font != current_format->font);
1823 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1824 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1826 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1827 if (buffer_format->cs.bold) {
1828 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1829 GINT_TO_POINTER (buffer_format->bold&0x1));
1831 if (buffer_format->cs.italic) {
1832 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1833 GINT_TO_POINTER (buffer_format->italic&0x1));
1835 if (buffer_format->cs.color) {
1836 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1837 GINT_TO_POINTER (&(buffer_format->color)));
1839 if (buffer_format->cs.font_size) {
1840 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1841 GINT_TO_POINTER (buffer_format->font_size));
1843 if (buffer_format->cs.justification) {
1844 switch (buffer_format->justification) {
1845 case GTK_JUSTIFY_LEFT:
1846 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1847 GINT_TO_POINTER(TRUE));
1849 case GTK_JUSTIFY_CENTER:
1850 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1851 GINT_TO_POINTER(TRUE));
1853 case GTK_JUSTIFY_RIGHT:
1854 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1855 GINT_TO_POINTER(TRUE));
1862 if (buffer_format->cs.font) {
1863 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1864 GINT_TO_POINTER (buffer_format->font));
1866 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1867 if (buffer_format->cs.bullet) {
1868 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
1869 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
1871 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1873 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
1875 g_free (buffer_format);
1876 g_free (current_format);
1878 /* Check dimming rules */
1879 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1880 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1884 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1886 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1888 ModestWindowPrivate *parent_priv;
1889 ModestMsgEditWindowPrivate *priv;
1890 GtkWidget *new_size_menuitem;
1891 GtkWidget *new_font_menuitem;
1893 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1894 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1896 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1897 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu");
1898 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1899 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1901 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatPlainTextMenu");
1902 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1903 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1906 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1908 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1909 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1911 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1912 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1914 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
1915 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
1918 switch (buffer_format->justification)
1920 case GTK_JUSTIFY_LEFT:
1921 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
1923 case GTK_JUSTIFY_CENTER:
1924 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
1926 case GTK_JUSTIFY_RIGHT:
1927 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
1934 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
1936 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1937 G_CALLBACK (modest_msg_edit_window_color_button_change),
1939 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1940 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1941 G_CALLBACK (modest_msg_edit_window_color_button_change),
1944 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1945 buffer_format->font_size))->data);
1946 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1950 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1951 markup = g_strconcat ("<span font_family='Sans'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1952 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1954 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1955 G_CALLBACK (modest_msg_edit_window_size_change),
1957 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1958 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1959 G_CALLBACK (modest_msg_edit_window_size_change),
1963 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1964 buffer_format->font))->data);
1965 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1969 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1970 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1971 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1973 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1974 G_CALLBACK (modest_msg_edit_window_font_change),
1976 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1977 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1978 G_CALLBACK (modest_msg_edit_window_font_change),
1982 g_free (buffer_format);
1986 #ifdef MODEST_HILDON_VERSION_0
1988 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1991 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1992 ModestMsgEditWindowPrivate *priv;
1993 GtkWidget *dialog = NULL;
1995 GdkColor *new_color = NULL;
1997 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1998 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2000 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2001 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2002 g_free (buffer_format);
2004 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2005 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2006 if (new_color != NULL) {
2007 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2008 (gpointer) new_color);
2011 gtk_widget_destroy (dialog);
2016 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2019 ModestMsgEditWindowPrivate *priv;
2020 GtkWidget *dialog = NULL;
2022 GdkColor *old_color = NULL;
2023 const GdkColor *new_color = NULL;
2025 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2026 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2028 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2029 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2031 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2032 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2033 if (new_color != NULL)
2034 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2036 gtk_widget_destroy (dialog);
2042 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2045 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2046 ModestMsgEditWindowPrivate *priv;
2047 GtkWidget *dialog = NULL;
2049 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2050 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2052 dialog = hildon_color_chooser_new ();
2053 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2054 g_free (buffer_format);
2056 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2058 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2059 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2062 gtk_widget_destroy (dialog);
2067 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2070 ModestMsgEditWindowPrivate *priv;
2071 GtkWidget *dialog = NULL;
2072 GdkColor *old_color = NULL;
2074 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2075 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2077 dialog = hildon_color_chooser_new ();
2078 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2080 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2082 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2083 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2085 gtk_widget_destroy (dialog);
2088 #endif /*!MODEST_HILDON_VERSION_0*/
2093 create_stream_for_uri (const gchar* uri)
2098 TnyStream *result = NULL;
2100 GnomeVFSHandle *handle = NULL;
2101 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2102 if (test == GNOME_VFS_OK) {
2103 TnyStream *vfssstream = TNY_STREAM (tny_vfs_stream_new (handle));
2104 /* Streams over OBEX (Bluetooth) are not seekable but
2105 * we expect them to be (we might need to read them
2106 * several times). So if this is a Bluetooth URI just
2107 * read the whole file into memory (this is not a fast
2108 * protocol so we can assume that these files are not
2109 * going to be very big) */
2110 if ((g_ascii_strncasecmp (uri, "obex://", 7) == 0)||
2111 (g_ascii_strncasecmp (uri, "upnpav://", 9) == 0)) {
2112 TnyStream *memstream = tny_camel_mem_stream_new ();
2113 tny_stream_write_to_stream (vfssstream, memstream);
2114 g_object_unref (vfssstream);
2117 result = vfssstream;
2125 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2128 ModestMsgEditWindowPrivate *priv;
2129 GtkWidget *dialog = NULL;
2131 GSList *uris = NULL;
2132 GSList *uri_node = NULL;
2134 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2136 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2137 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2138 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2140 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2142 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2143 GTK_WINDOW (dialog), GTK_WINDOW (window));
2145 response = gtk_dialog_run (GTK_DIALOG (dialog));
2147 case GTK_RESPONSE_OK:
2148 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2153 gtk_widget_destroy (dialog);
2155 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2157 GnomeVFSHandle *handle = NULL;
2158 GnomeVFSResult result;
2159 GtkTextIter position;
2160 GtkTextMark *insert_mark;
2162 uri = (const gchar *) uri_node->data;
2163 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2164 if (result == GNOME_VFS_OK) {
2166 GnomeVFSFileInfo *info;
2167 gchar *filename, *basename, *escaped_filename;
2168 TnyMimePart *mime_part;
2170 const gchar *mime_type = NULL;
2171 GnomeVFSURI *vfs_uri;
2172 guint64 stream_size;
2174 gnome_vfs_close (handle);
2175 vfs_uri = gnome_vfs_uri_new (uri);
2177 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2178 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2179 g_free (escaped_filename);
2180 gnome_vfs_uri_unref (vfs_uri);
2181 info = gnome_vfs_file_info_new ();
2183 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2184 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2186 mime_type = gnome_vfs_file_info_get_mime_type (info);
2188 mime_part = tny_platform_factory_new_mime_part
2189 (modest_runtime_get_platform_factory ());
2191 TnyStream *stream = create_stream_for_uri (uri);
2193 if (stream == NULL) {
2195 modest_platform_information_banner (NULL, NULL, dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2197 g_object_unref (mime_part);
2198 gnome_vfs_file_info_unref (info);
2202 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2204 content_id = g_strdup_printf ("%d", priv->next_cid);
2205 tny_mime_part_set_content_id (mime_part, content_id);
2206 g_free (content_id);
2209 basename = g_path_get_basename (filename);
2210 tny_mime_part_set_filename (mime_part, basename);
2213 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size);
2215 if (pixbuf != NULL) {
2216 priv->images_size += stream_size;
2217 priv->images_count ++;
2218 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2219 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2220 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
2221 g_object_unref (pixbuf);
2224 tny_list_prepend (priv->images, (GObject *) mime_part);
2225 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2227 g_object_unref (mime_part);
2228 gnome_vfs_file_info_unref (info);
2237 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2239 GtkWidget *dialog = NULL;
2241 GSList *uris = NULL;
2243 GnomeVFSFileSize total_size, allowed_size;
2244 ModestMsgEditWindowPrivate *priv;
2248 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(window));
2250 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2252 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2255 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2256 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2257 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2258 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), GTK_WINDOW (window));
2260 response = gtk_dialog_run (GTK_DIALOG (dialog));
2262 case GTK_RESPONSE_OK:
2263 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2268 gtk_widget_destroy (dialog);
2270 /* allowed size is the maximum size - what's already there */
2271 modest_attachments_view_get_sizes (
2272 MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2273 &att_num, &att_size);
2274 allowed_size = MODEST_MAX_ATTACHMENT_SIZE - att_size;
2277 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2279 const gchar *uri = (const gchar *) uri_node->data;
2281 total_size += modest_msg_edit_window_attach_file_one
2282 (window, uri, allowed_size);
2284 if (total_size > allowed_size) {
2285 g_warning ("%s: total size: %u",
2286 __FUNCTION__, (unsigned int)total_size);
2290 allowed_size -= total_size;
2294 g_slist_foreach (uris, (GFunc) g_free, NULL);
2295 g_slist_free (uris);
2300 modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window,
2302 GnomeVFSFileSize allowed_size)
2305 GnomeVFSHandle *handle = NULL;
2306 ModestMsgEditWindowPrivate *priv;
2307 GnomeVFSResult result;
2308 GnomeVFSFileSize size = 0;
2309 g_return_val_if_fail (window, 0);
2310 g_return_val_if_fail (uri, 0);
2312 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2314 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2315 if (result == GNOME_VFS_OK) {
2316 TnyMimePart *mime_part;
2318 const gchar *mime_type = NULL;
2320 gchar *escaped_filename;
2323 GnomeVFSFileInfo *info;
2324 GnomeVFSURI *vfs_uri;
2326 gnome_vfs_close (handle);
2327 vfs_uri = gnome_vfs_uri_new (uri);
2330 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2331 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2332 g_free (escaped_filename);
2333 gnome_vfs_uri_unref (vfs_uri);
2335 info = gnome_vfs_file_info_new ();
2337 if (gnome_vfs_get_file_info (uri,
2339 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2341 mime_type = gnome_vfs_file_info_get_mime_type (info);
2342 mime_part = tny_platform_factory_new_mime_part
2343 (modest_runtime_get_platform_factory ());
2345 /* try to get the attachment's size; this may fail for weird
2346 * file systems, like obex, upnp... */
2347 if (allowed_size != 0 &&
2348 info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
2350 if (size > allowed_size) {
2351 modest_platform_information_banner (NULL, NULL,
2352 dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2356 g_warning ("%s: could not get attachment size", __FUNCTION__);
2358 stream = create_stream_for_uri (uri);
2360 if (stream == NULL) {
2362 modest_platform_information_banner (NULL, NULL, dgettext("hildon-fm", "sfil_ib_opening_not_allowed"));
2364 g_object_unref (mime_part);
2365 gnome_vfs_file_info_unref (info);
2369 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2370 g_object_unref (stream);
2372 content_id = g_strdup_printf ("%d", priv->next_cid);
2373 tny_mime_part_set_content_id (mime_part, content_id);
2374 g_free (content_id);
2377 basename = g_path_get_basename (filename);
2378 tny_mime_part_set_filename (mime_part, basename);
2381 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2382 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2384 info->size == 0, info->size);
2385 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2386 gtk_widget_show_all (priv->attachments_caption);
2387 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2389 g_object_unref (mime_part);
2390 gnome_vfs_file_info_unref (info);
2397 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2400 ModestMsgEditWindowPrivate *priv;
2403 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2404 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2406 if (att_list == NULL) {
2407 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2409 g_object_ref (att_list);
2412 if (tny_list_get_length (att_list) == 0) {
2413 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2415 gboolean dialog_response;
2416 gchar *message = NULL;
2417 gchar *filename = NULL;
2419 if (tny_list_get_length (att_list) == 1) {
2421 iter = tny_list_create_iterator (att_list);
2422 part = (TnyMimePart *) tny_iterator_get_current (iter);
2423 g_object_unref (iter);
2424 if (TNY_IS_MSG (part)) {
2425 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2427 filename = tny_header_dup_subject (header);
2428 g_object_unref (header);
2430 if (filename == NULL) {
2431 filename = g_strdup (_("mail_va_no_subject"));
2434 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2436 g_object_unref (part);
2438 filename = g_strdup ("");
2440 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
2441 tny_list_get_length (att_list)), filename);
2444 dialog_response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window), message);
2447 if (dialog_response != GTK_RESPONSE_OK) {
2448 g_object_unref (att_list);
2451 hildon_banner_show_information (NULL, NULL, _("mcen_me_inbox_remove_attachments"));
2453 for (iter = tny_list_create_iterator (att_list);
2454 !tny_iterator_is_done (iter);
2455 tny_iterator_next (iter)) {
2456 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2457 const gchar *att_id;
2458 tny_list_remove (priv->attachments, (GObject *) mime_part);
2460 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2462 if (tny_list_get_length (priv->attachments) == 0)
2463 gtk_widget_hide (priv->attachments_caption);
2464 att_id = tny_mime_part_get_content_id (mime_part);
2466 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2468 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2469 g_object_unref (mime_part);
2471 g_object_unref (iter);
2474 g_object_unref (att_list);
2476 /* if the last attachment has been removed, focus the Subject: field */
2477 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2478 gtk_widget_grab_focus (priv->subject_field);
2482 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2485 ModestMsgEditWindowPrivate *priv;
2486 GdkColor *new_color;
2487 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2489 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2490 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2493 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2495 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2497 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2499 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2504 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
2507 ModestMsgEditWindowPrivate *priv;
2508 gint new_size_index;
2509 ModestMsgEditWindow *window;
2512 window = MODEST_MSG_EDIT_WINDOW (userdata);
2513 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2514 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2516 if (gtk_check_menu_item_get_active (menu_item)) {
2518 WPTextBufferFormat format;
2520 memset (&format, 0, sizeof (format));
2521 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2523 label = gtk_bin_get_child (GTK_BIN (menu_item));
2525 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
2526 format.cs.font_size = TRUE;
2527 format.cs.text_position = TRUE;
2528 format.cs.font = TRUE;
2529 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
2530 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2532 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2533 GINT_TO_POINTER (wp_get_font_size_index (new_size_index, 12))))
2534 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2536 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2537 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
2538 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2544 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
2547 ModestMsgEditWindowPrivate *priv;
2548 gint new_font_index;
2549 ModestMsgEditWindow *window;
2552 window = MODEST_MSG_EDIT_WINDOW (userdata);
2553 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2554 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2556 if (gtk_check_menu_item_get_active (menu_item)) {
2559 label = gtk_bin_get_child (GTK_BIN (menu_item));
2561 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
2563 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2564 GINT_TO_POINTER(new_font_index)))
2565 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2567 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2568 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
2569 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2575 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2578 ModestMsgEditWindowPrivate *priv = NULL;
2579 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2581 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2582 if (!priv->update_caption_visibility)
2585 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2587 gtk_widget_show (priv->cc_caption);
2589 gtk_widget_hide (priv->cc_caption);
2591 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2595 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2598 ModestMsgEditWindowPrivate *priv = NULL;
2599 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2601 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2602 if (!priv->update_caption_visibility)
2605 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2607 gtk_widget_show (priv->bcc_caption);
2609 gtk_widget_hide (priv->bcc_caption);
2611 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2615 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2616 ModestRecptEditor *editor)
2618 ModestMsgEditWindowPrivate *priv;
2620 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2621 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2623 /* we check for low-mem; in that case, show a warning, and don't allow
2624 * for the addressbook
2626 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2629 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2631 if (editor == NULL) {
2632 GtkWidget *view_focus;
2633 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2635 /* This code should be kept in sync with ModestRecptEditor. The
2636 textview inside the recpt editor is the one that really gets the
2637 focus. As it's inside a scrolled window, and this one inside the
2638 hbox recpt editor inherits from, we'll need to go up in the
2639 hierarchy to know if the text view is part of the recpt editor
2640 or if it's a different text entry */
2642 if (gtk_widget_get_parent (view_focus)) {
2643 GtkWidget *first_parent;
2645 first_parent = gtk_widget_get_parent (view_focus);
2646 if (gtk_widget_get_parent (first_parent) &&
2647 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2648 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2653 editor = MODEST_RECPT_EDITOR (priv->to_field);
2657 modest_address_book_select_addresses (editor);
2662 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2664 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2666 modest_msg_edit_window_open_addressbook (window, NULL);
2670 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2671 gboolean show_toolbar)
2673 ModestWindowPrivate *parent_priv;
2675 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2676 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2678 /* We can not just use the code of
2679 modest_msg_edit_window_setup_toolbar because it has a
2680 mixture of both initialization and creation code. */
2682 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2684 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2688 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2689 TnyHeaderFlags priority_flags)
2691 ModestMsgEditWindowPrivate *priv;
2692 ModestWindowPrivate *parent_priv;
2694 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2696 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2697 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2699 if (priv->priority_flags != priority_flags) {
2700 GtkAction *priority_action = NULL;
2702 priv->priority_flags = priority_flags;
2704 switch (priority_flags) {
2705 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2706 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2707 MODEST_HEADER_ICON_HIGH,
2708 HILDON_ICON_SIZE_XSMALL);
2709 gtk_widget_show (priv->priority_icon);
2710 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2711 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2713 case TNY_HEADER_FLAG_LOW_PRIORITY:
2714 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2715 MODEST_HEADER_ICON_LOW,
2716 HILDON_ICON_SIZE_XSMALL);
2717 gtk_widget_show (priv->priority_icon);
2718 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2719 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2722 gtk_widget_hide (priv->priority_icon);
2723 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2724 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2727 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2728 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2733 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2736 ModestMsgEditWindowPrivate *priv;
2737 ModestWindowPrivate *parent_priv;
2738 gint current_format;
2740 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2742 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2743 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2745 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2746 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2748 if (current_format != file_format) {
2749 switch (file_format) {
2750 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2751 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2752 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
2754 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2758 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2759 response = gtk_dialog_run (GTK_DIALOG (dialog));
2760 gtk_widget_destroy (dialog);
2761 if (response == GTK_RESPONSE_OK) {
2762 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2764 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu"));
2765 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
2770 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2771 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2772 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2777 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2780 ModestMsgEditWindowPrivate *priv;
2781 WPTextBufferFormat oldfmt, fmt;
2782 gint old_position = 0;
2786 GdkColor *color = NULL;
2787 gboolean bold, bold_set, italic, italic_set;
2788 gboolean underline, underline_set;
2789 gboolean strikethrough, strikethrough_set;
2790 gboolean position_set;
2791 gboolean font_size_set, font_set, color_set;
2794 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2795 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2797 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2798 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(),
2799 GTK_WINDOW(dialog), GTK_WINDOW (window));
2801 /* First we get the currently selected font information */
2802 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2804 switch (oldfmt.text_position) {
2805 case TEXT_POSITION_NORMAL:
2808 case TEXT_POSITION_SUPERSCRIPT:
2816 g_object_set (G_OBJECT (dialog),
2817 "bold", oldfmt.bold != FALSE,
2818 "bold-set", !oldfmt.cs.bold,
2819 "underline", oldfmt.underline != FALSE,
2820 "underline-set", !oldfmt.cs.underline,
2821 "italic", oldfmt.italic != FALSE,
2822 "italic-set", !oldfmt.cs.italic,
2823 "strikethrough", oldfmt.strikethrough != FALSE,
2824 "strikethrough-set", !oldfmt.cs.strikethrough,
2825 "color", &oldfmt.color,
2826 "color-set", !oldfmt.cs.color,
2827 "size", wp_font_size[oldfmt.font_size],
2828 "size-set", !oldfmt.cs.font_size,
2829 "position", old_position,
2830 "position-set", !oldfmt.cs.text_position,
2831 "family", wp_get_font_name (oldfmt.font),
2832 "family-set", !oldfmt.cs.font,
2835 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2836 GTK_WINDOW (dialog), GTK_WINDOW (window));
2837 gtk_widget_show_all (dialog);
2838 priv->font_dialog = dialog;
2839 response = gtk_dialog_run (GTK_DIALOG (dialog));
2840 priv->font_dialog = NULL;
2841 if (response == GTK_RESPONSE_OK) {
2843 g_object_get( dialog,
2845 "bold-set", &bold_set,
2846 "underline", &underline,
2847 "underline-set", &underline_set,
2849 "italic-set", &italic_set,
2850 "strikethrough", &strikethrough,
2851 "strikethrough-set", &strikethrough_set,
2853 "color-set", &color_set,
2855 "size-set", &font_size_set,
2856 "family", &font_name,
2857 "family-set", &font_set,
2858 "position", &position,
2859 "position-set", &position_set,
2864 if (response == GTK_RESPONSE_OK) {
2865 memset(&fmt, 0, sizeof(fmt));
2871 fmt.italic = italic;
2872 fmt.cs.italic = TRUE;
2874 if (underline_set) {
2875 fmt.underline = underline;
2876 fmt.cs.underline = TRUE;
2878 if (strikethrough_set) {
2879 fmt.strikethrough = strikethrough;
2880 fmt.cs.strikethrough = TRUE;
2885 ? TEXT_POSITION_NORMAL
2886 : ( ( position == 1 )
2887 ? TEXT_POSITION_SUPERSCRIPT
2888 : TEXT_POSITION_SUBSCRIPT );
2889 fmt.cs.text_position = TRUE;
2890 fmt.font_size = oldfmt.font_size;
2894 fmt.cs.color = TRUE;
2897 fmt.font = wp_get_font_index(font_name,
2902 if (font_size_set) {
2903 fmt.cs.font_size = TRUE;
2904 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
2906 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2907 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
2909 gtk_widget_destroy (dialog);
2911 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2915 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2917 ModestMsgEditWindowPrivate *priv;
2919 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2920 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2922 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2924 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2925 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2929 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2931 ModestMsgEditWindowPrivate *priv;
2933 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2934 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2936 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2938 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
2939 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2944 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2946 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2948 priv->can_undo = can_undo;
2952 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2954 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2956 priv->can_redo = can_redo;
2960 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
2962 ModestMsgEditWindowPrivate *priv;
2963 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2964 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2966 return priv->can_undo;
2970 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
2972 ModestMsgEditWindowPrivate *priv;
2973 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2974 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2976 return priv->can_redo;
2981 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2984 GtkTextIter match_start, match_end;
2986 if (image_id == NULL)
2989 gtk_text_buffer_get_start_iter (buffer, &iter);
2991 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2992 GSList *tags = gtk_text_iter_get_tags (&match_start);
2994 for (node = tags; node != NULL; node = g_slist_next (node)) {
2995 GtkTextTag *tag = (GtkTextTag *) node->data;
2996 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2997 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2998 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
3000 offset = gtk_text_iter_get_offset (&match_start);
3001 gtk_text_buffer_delete (buffer, &match_start, &match_end);
3002 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
3006 gtk_text_iter_forward_char (&iter);
3011 message_is_empty (ModestMsgEditWindow *window)
3013 ModestMsgEditWindowPrivate *priv = NULL;
3015 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3016 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3018 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
3019 * so we can ignore markup.
3021 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
3024 count = gtk_text_buffer_get_char_count (buf);
3030 msg_body_focus (GtkWidget *focus,
3031 GdkEventFocus *event,
3035 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3036 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3037 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3042 recpt_field_changed (GtkTextBuffer *buffer,
3043 ModestMsgEditWindow *editor)
3045 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3046 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3050 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3052 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3053 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3057 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3060 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3061 GtkTextBuffer *buffer;
3063 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3064 gtk_text_buffer_set_modified (buffer, modified);
3065 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3066 gtk_text_buffer_set_modified (buffer, modified);
3067 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3068 gtk_text_buffer_set_modified (buffer, modified);
3069 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3073 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3075 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3076 const char *account_name;
3077 GtkTextBuffer *buffer;
3079 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3080 if (gtk_text_buffer_get_modified (buffer))
3082 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3083 if (gtk_text_buffer_get_modified (buffer))
3085 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3086 if (gtk_text_buffer_get_modified (buffer))
3088 if (gtk_text_buffer_get_modified (priv->text_buffer))
3090 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3091 if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3102 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3104 ModestMsgEditWindowPrivate *priv = NULL;
3106 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3107 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3109 /* check if there's no recipient added */
3110 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3111 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3112 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3113 /* no recipient contents, then select contacts */
3114 modest_msg_edit_window_open_addressbook (window, NULL);
3118 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3119 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3122 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3123 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3126 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3127 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3131 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3132 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3133 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3140 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3141 ModestMsgEditWindow *window)
3143 modest_msg_edit_window_offer_attach_file (window);
3147 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3149 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3151 return priv->clipboard_text;
3155 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3157 ModestMsgEditWindow *window)
3159 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3160 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3162 if (!GTK_WIDGET_VISIBLE (window))
3165 g_object_ref (window);
3166 text = gtk_clipboard_wait_for_text (selection_clipboard);
3168 if (priv->clipboard_text != NULL) {
3169 g_free (priv->clipboard_text);
3171 priv->clipboard_text = text;
3173 if (GTK_WIDGET_VISIBLE (window)) {
3174 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3176 g_object_unref (window);
3179 static gboolean clipboard_owner_change_idle (gpointer userdata)
3181 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
3182 ModestMsgEditWindowPrivate *priv;
3184 gdk_threads_enter ();
3185 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3186 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3188 priv->clipboard_owner_idle = 0;
3189 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, window);
3190 gdk_threads_leave ();
3196 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window)
3198 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3199 if (priv->clipboard_owner_idle == 0) {
3200 priv->clipboard_owner_idle = g_idle_add (clipboard_owner_change_idle, window);
3205 subject_field_move_cursor (GtkEntry *entry,
3206 GtkMovementStep step,
3211 if (!GTK_WIDGET_VISIBLE (window))
3214 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3218 update_window_title (ModestMsgEditWindow *window)
3220 ModestMsgEditWindowPrivate *priv = NULL;
3221 const gchar *subject;
3223 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3224 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3225 if (subject == NULL || subject[0] == '\0')
3226 subject = _("mail_va_new_email");
3228 gtk_window_set_title (GTK_WINDOW (window), subject);
3233 subject_field_changed (GtkEditable *editable,
3234 ModestMsgEditWindow *window)
3236 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3237 update_window_title (window);
3238 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3239 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3240 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3244 subject_field_insert_text (GtkEditable *editable,
3246 gint new_text_length,
3248 ModestMsgEditWindow *window)
3250 GString *result = g_string_new ("");
3252 gint result_len = 0;
3253 const gchar *entry_text = NULL;
3256 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3257 old_length = g_utf8_strlen (entry_text, -1);
3259 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3260 gunichar c = g_utf8_get_char_validated (current, 8);
3261 /* Invalid unichar, stop */
3267 result = g_string_append_unichar (result, c);
3271 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3272 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3275 /* Prevent endless recursion */
3276 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3277 g_signal_emit_by_name (editable, "insert-text",
3278 (gpointer) result->str, (gpointer) result->len,
3279 (gpointer) position, (gpointer) window);
3280 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3284 if (result_len + old_length > 1000) {
3285 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3286 dgettext("hildon-common-strings",
3287 "ckdg_ib_maximum_characters_reached"));
3290 g_string_free (result, TRUE);
3294 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3297 ModestMsgEditWindowPrivate *priv = NULL;
3299 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3300 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3302 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3305 gtk_widget_show_all (priv->find_toolbar);
3306 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3308 gtk_widget_hide_all (priv->find_toolbar);
3309 gtk_widget_grab_focus (priv->msg_body);
3315 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3317 GtkTextIter *match_start,
3318 GtkTextIter *match_end)
3320 GtkTextIter end_iter;
3321 gchar *str_casefold;
3324 gchar *range_casefold;
3327 gboolean result = FALSE;
3334 gtk_text_iter_forward_to_end (&end_iter);
3336 str_casefold = g_utf8_casefold (str, -1);
3337 str_chars_n = strlen (str);
3339 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3340 range_casefold = g_utf8_casefold (range_text, -1);
3341 range_chars_n = strlen (range_casefold);
3343 if (range_chars_n < str_chars_n) {
3344 g_free (str_casefold);
3345 g_free (range_text);
3346 g_free (range_casefold);
3350 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3351 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3352 if (!g_utf8_collate (range_subtext, str_casefold)) {
3353 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3355 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3356 match_start, match_end, NULL);
3357 g_free (found_text);
3359 g_free (range_subtext);
3363 g_free (str_casefold);
3364 g_free (range_text);
3365 g_free (range_casefold);
3372 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3373 ModestMsgEditWindow *window)
3375 gchar *current_search = NULL;
3376 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3378 GtkTextIter selection_start, selection_end;
3379 GtkTextIter match_start, match_end;
3380 gboolean continue_search = FALSE;
3382 if (message_is_empty (window)) {
3383 g_free (priv->last_search);
3384 priv->last_search = NULL;
3385 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3389 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3390 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3391 g_free (current_search);
3392 g_free (priv->last_search);
3393 priv->last_search = NULL;
3394 /* Information banner about empty search */
3395 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
3399 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3400 continue_search = TRUE;
3402 g_free (priv->last_search);
3403 priv->last_search = g_strdup (current_search);
3406 if (continue_search) {
3407 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3408 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3409 &match_start, &match_end);
3411 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
3413 GtkTextIter buffer_start;
3414 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3415 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3416 &match_start, &match_end);
3418 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
3421 /* Mark as selected the string found in search */
3423 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3424 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3425 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3427 g_free (priv->last_search);
3428 priv->last_search = NULL;
3430 g_free (current_search);
3434 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3435 ModestMsgEditWindow *window)
3437 GtkToggleAction *toggle;
3438 ModestWindowPrivate *parent_priv;
3439 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3441 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
3442 gtk_toggle_action_set_active (toggle, FALSE);
3446 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3448 ModestMsgEditWindowPrivate *priv;
3450 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3455 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3458 ModestMsgEditWindowPrivate *priv;
3460 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3466 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3469 ModestMsgEditWindowPrivate *priv;
3470 TnyHeader *header = NULL;
3472 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3473 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3475 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3476 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3478 if (priv->draft_msg != NULL) {
3479 g_object_unref (priv->draft_msg);
3482 if (draft != NULL) {
3483 g_object_ref (draft);
3484 header = tny_msg_get_header (draft);
3485 if (priv->msg_uid) {
3486 g_free (priv->msg_uid);
3487 priv->msg_uid = NULL;
3489 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3490 if (GTK_WIDGET_REALIZED (window)) {
3491 if (!modest_window_mgr_register_window (mgr, MODEST_WINDOW (window), NULL)) {
3492 gtk_widget_destroy (GTK_WIDGET (window));
3498 priv->draft_msg = draft;
3502 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3503 GtkTextIter *start, GtkTextIter *end,
3506 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3507 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3510 if (tag == NULL) return;
3511 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3512 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3513 replace_with_images (window, priv->images);
3518 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3521 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3523 g_return_if_fail (TNY_IS_MIME_PART (part));
3524 tny_list_prepend (priv->attachments, (GObject *) part);
3525 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3526 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3527 gtk_widget_show_all (priv->attachments_caption);
3528 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3532 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3534 ModestMsgEditWindowPrivate *priv;
3536 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3537 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3539 return priv->msg_uid;
3543 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3544 ModestMsgEditWindowWidgetType widget_type)
3546 ModestMsgEditWindowPrivate *priv;
3548 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3549 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3551 switch (widget_type) {
3552 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3553 return priv->msg_body;
3555 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3556 return priv->to_field;
3558 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3559 return priv->cc_field;
3561 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3562 return priv->bcc_field;
3564 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3565 return priv->subject_field;
3567 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3568 return priv->attachments_view;
3576 remove_tags (WPTextBuffer *buffer)
3578 GtkTextIter start, end;
3580 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3581 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3583 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3587 on_account_removed (TnyAccountStore *account_store,
3588 TnyAccount *account,
3591 /* Do nothing if it's a store account, because we use the
3592 transport to send the messages */
3593 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3594 const gchar *parent_acc = NULL;
3595 const gchar *our_acc = NULL;
3597 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3598 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3599 /* Close this window if I'm showing a message of the removed account */
3600 if (strcmp (parent_acc, our_acc) == 0)
3601 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3606 on_zoom_minus_plus_not_implemented (ModestWindow *window)
3608 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3610 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
3616 set_zoom_do_nothing (ModestWindow *window,
3622 get_zoom_do_nothing (ModestWindow *window)
3628 on_priority_toggle (HildonCheckButton *button,
3629 GSList *priority_group)
3631 if (hildon_check_button_get_active (button)) {
3634 for (node = priority_group; node != NULL; node = g_slist_next (node)) {
3635 HildonCheckButton *node_button = (HildonCheckButton *) node->data;
3636 if ((node_button != button) &&
3637 hildon_check_button_get_active (node_button)) {
3638 hildon_check_button_set_active (node_button, FALSE);
3645 modest_msg_edit_window_show_msg_settings_dialog (ModestMsgEditWindow *window)
3649 GtkWidget *priority_hbox;
3650 GtkWidget *high_toggle, *medium_toggle, *low_toggle;
3651 GtkWidget *captioned;
3652 GtkSizeGroup *title_sizegroup, *value_sizegroup;
3653 GSList *priority_group = NULL;
3655 title_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
3656 value_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
3658 dialog = gtk_dialog_new ();
3659 vbox = gtk_vbox_new (FALSE, 0);
3660 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), vbox);
3661 gtk_widget_show (vbox);
3663 priority_hbox = gtk_hbox_new (0, TRUE);
3664 high_toggle = hildon_check_button_new (HILDON_SIZE_FINGER_HEIGHT);
3665 gtk_button_set_label (GTK_BUTTON (high_toggle), _("TDHigh"));
3666 priority_group = g_slist_prepend (priority_group, high_toggle);
3667 medium_toggle = hildon_check_button_new (HILDON_SIZE_FINGER_HEIGHT);
3668 gtk_button_set_label (GTK_BUTTON (medium_toggle), _("TDMedium"));
3669 priority_group = g_slist_prepend (priority_group, medium_toggle);
3670 low_toggle = hildon_check_button_new (HILDON_SIZE_FINGER_HEIGHT);
3671 gtk_button_set_label (GTK_BUTTON (low_toggle), _("TDLow"));
3672 priority_group = g_slist_prepend (priority_group, low_toggle);
3673 gtk_box_pack_start (GTK_BOX (priority_hbox), low_toggle, FALSE, FALSE, 0);
3674 gtk_box_pack_start (GTK_BOX (priority_hbox), medium_toggle, FALSE, FALSE, 0);
3675 gtk_box_pack_start (GTK_BOX (priority_hbox), high_toggle, FALSE, FALSE, 0);
3676 g_signal_connect (G_OBJECT (high_toggle), "toggled", G_CALLBACK (on_priority_toggle), priority_group);
3677 g_signal_connect (G_OBJECT (medium_toggle), "toggled", G_CALLBACK (on_priority_toggle), priority_group);
3678 g_signal_connect (G_OBJECT (low_toggle), "toggled", G_CALLBACK (on_priority_toggle), priority_group);
3679 gtk_widget_show_all (priority_hbox);
3680 captioned = modest_maemo_utils_create_captioned (title_sizegroup, value_sizegroup,
3681 _("TODO: Priority"), priority_hbox);
3682 gtk_widget_show (captioned);
3683 gtk_box_pack_start (GTK_BOX (vbox), captioned, FALSE, FALSE, 0);
3685 g_object_unref (title_sizegroup);
3686 g_object_unref (value_sizegroup);
3688 /* Set current values */
3690 gtk_dialog_run (GTK_DIALOG (dialog));
3692 /* Read new values */
3694 gtk_widget_destroy (dialog);
3695 g_slist_free (priority_group);
3699 static void on_message_settings (GtkAction *action,
3700 ModestMsgEditWindow *window)
3702 modest_msg_edit_window_show_msg_settings_dialog (window);