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>
39 #include <modest-account-protocol.h>
43 #include <modest-account-mgr.h>
44 #include <modest-account-mgr-helpers.h>
46 #include <widgets/modest-msg-edit-window.h>
47 #include <modest-selector-picker.h>
48 #include <widgets/modest-recpt-editor.h>
49 #include <widgets/modest-attachments-view.h>
51 #include <modest-runtime.h>
53 #include "modest-platform.h"
54 #include "modest-icon-names.h"
55 #include "modest-widget-memory.h"
56 #include "modest-window-priv.h"
57 #include "modest-mail-operation.h"
58 #include "modest-tny-platform-factory.h"
59 #include "modest-tny-msg.h"
60 #include "modest-tny-folder.h"
61 #include "modest-tny-account.h"
62 #include "modest-address-book.h"
63 #include "modest-text-utils.h"
64 #include <tny-simple-list.h>
65 #include <modest-wp-text-view.h>
66 #include <wptextbuffer.h>
67 #include <hildon/hildon-pannable-area.h>
68 #include <hildon/hildon-touch-selector.h>
69 #include <hildon/hildon-picker-dialog.h>
70 #include "modest-msg-edit-window-ui-dimming.h"
72 #include "modest-hildon-includes.h"
73 #ifdef MODEST_HAVE_HILDON0_WIDGETS
74 #include <hildon-widgets/hildon-color-chooser.h>
76 #include "widgets/modest-msg-edit-window-ui.h"
77 #ifdef MODEST_HAVE_HILDON0_WIDGETS
78 #include <libgnomevfs/gnome-vfs-mime-utils.h>
80 #include <libgnomevfs/gnome-vfs-mime.h>
82 #include <modest-utils.h>
83 #include "modest-maemo-utils.h"
84 #include <modest-ui-constants.h>
87 #define DEFAULT_FONT_SIZE 3
88 #define DEFAULT_FONT 2
89 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
90 #define DEFAULT_MAIN_VBOX_SPACING 6
91 #define SUBJECT_MAX_LENGTH 1000
92 #define IMAGE_MAX_WIDTH 560
93 #define DEFAULT_FONT_SCALE 1.5
94 #define ATTACHMENT_BUTTON_WIDTH 118
96 static gboolean is_wp_text_buffer_started = FALSE;
98 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
99 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
100 static void modest_msg_edit_window_finalize (GObject *obj);
102 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
103 static void body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
104 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
106 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
107 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
108 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
109 static void text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
110 GtkTextIter *start, GtkTextIter *end,
112 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
113 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
114 static void subject_field_insert_text (GtkEditable *editable,
116 gint new_text_length,
118 ModestMsgEditWindow *window);
119 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
121 static void modest_msg_edit_window_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 void init_window (ModestMsgEditWindow *obj);
161 gboolean scroll_drag_timeout (gpointer userdata);
162 static void correct_scroll (ModestMsgEditWindow *w);
163 static void correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused);
164 static void text_buffer_end_user_action (GtkTextBuffer *buffer,
165 ModestMsgEditWindow *userdata);
166 static void text_buffer_mark_set (GtkTextBuffer *buffer,
169 ModestMsgEditWindow *userdata);
170 static void on_message_settings (GtkAction *action,
171 ModestMsgEditWindow *window);
172 static void setup_menu (ModestMsgEditWindow *self);
174 static void from_field_changed (HildonPickerButton *button,
175 ModestMsgEditWindow *self);
176 static void font_size_clicked (GtkToolButton *button,
177 ModestMsgEditWindow *window);
178 static void font_face_clicked (GtkToolButton *button,
179 ModestMsgEditWindow *window);
180 static void update_signature (ModestMsgEditWindow *self,
181 const gchar *old_account,
182 const gchar *new_account);
183 static void DEBUG_BUFFER (WPTextBuffer *buffer)
187 g_message ("BEGIN BUFFER OF SIZE %d", gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (buffer)));
189 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
190 while (!gtk_text_iter_is_end (&iter)) {
191 GString *output = g_string_new ("");
192 GSList *toggled_tags;
195 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
196 g_string_append_printf (output, "%d: CLOSED [ ", gtk_text_iter_get_offset (&iter));
197 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
198 GtkTextTag *tag = (GtkTextTag *) node->data;
200 g_object_get (G_OBJECT (tag), "name", &name, NULL);
201 output = g_string_append (output, name);
202 g_string_append (output, " ");
204 output = g_string_append (output, "] OPENED [ ");
205 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
206 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
207 GtkTextTag *tag = (GtkTextTag *) node->data;
209 g_object_get (G_OBJECT (tag), "name", &name, NULL);
210 output = g_string_append (output, name);
211 g_string_append (output, " ");
213 output = g_string_append (output, "]\n");
214 g_message ("%s", output->str);
215 g_string_free (output, TRUE);
216 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
218 g_message ("END BUFFER");
222 static const GtkActionEntry hildon2_msg_edit_action_entries [] = {
223 { "MessageSettings", NULL, N_("mcen_me_message_settings"), NULL, NULL, G_CALLBACK (on_message_settings)},
227 /* static gboolean */
228 /* on_key_pressed (GtkWidget *self, */
229 /* GdkEventKey *event, */
230 /* gpointer user_data); */
232 /* list my signals */
239 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
240 struct _ModestMsgEditWindowPrivate {
242 GtkWidget *header_box;
244 ModestPairList *from_field_protos;
245 GtkWidget *from_field;
246 gchar *last_from_account;
247 gchar *original_account_name;
252 gchar *original_mailbox;
256 GtkWidget *bcc_field;
257 GtkWidget *subject_field;
258 GtkWidget *attachments_view;
259 GtkWidget *priority_icon;
260 GtkWidget *subject_box;
261 GtkWidget *add_attachment_button;
263 GtkWidget *cc_caption;
264 GtkWidget *bcc_caption;
265 gboolean update_caption_visibility;
266 GtkWidget *attachments_caption;
268 GtkTextBuffer *text_buffer;
270 GtkWidget *font_size_toolitem;
271 GtkWidget *font_face_toolitem;
272 GtkWidget *font_color_button;
273 GtkWidget *font_color_toolitem;
274 GSList *font_items_group;
275 GtkTreeModel *faces_model;
276 gint current_face_index;
277 GtkWidget *font_tool_button_label;
278 GtkTreeModel *sizes_model;
279 gint current_size_index;
280 GtkWidget *size_tool_button_label;
282 GtkWidget *find_toolbar;
285 GtkWidget *font_dialog;
288 guint correct_scroll_idle;
289 guint scroll_drag_timeout_id;
293 TnyList *attachments;
298 TnyHeaderFlags priority_flags;
300 gboolean can_undo, can_redo;
301 gulong clipboard_change_handler_id;
302 gulong default_clipboard_change_handler_id;
303 gulong account_removed_handler_id;
304 guint clipboard_owner_idle;
305 gchar *clipboard_text;
314 GtkWidget *cc_button;
315 GtkWidget *bcc_button;
318 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
319 MODEST_TYPE_MSG_EDIT_WINDOW, \
320 ModestMsgEditWindowPrivate))
322 static GtkWindowClass *parent_class = NULL;
324 /* uncomment the following if you have defined any signals */
325 /* static guint signals[LAST_SIGNAL] = {0}; */
328 modest_msg_edit_window_get_type (void)
330 static GType my_type = 0;
332 static const GTypeInfo my_info = {
333 sizeof(ModestMsgEditWindowClass),
334 NULL, /* base init */
335 NULL, /* base finalize */
336 (GClassInitFunc) modest_msg_edit_window_class_init,
337 NULL, /* class finalize */
338 NULL, /* class data */
339 sizeof(ModestMsgEditWindow),
341 (GInstanceInitFunc) modest_msg_edit_window_init,
344 my_type = g_type_register_static (MODEST_TYPE_HILDON2_WINDOW,
345 "ModestMsgEditWindow",
353 save_state (ModestWindow *self)
355 modest_widget_memory_save (modest_runtime_get_conf(),
356 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
361 restore_settings (ModestMsgEditWindow *self)
363 ModestConf *conf = NULL;
365 conf = modest_runtime_get_conf ();
367 /* Dim at start clipboard actions */
368 modest_widget_memory_restore (conf, G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
373 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
375 GObjectClass *gobject_class;
376 ModestWindowClass *modest_window_class;
377 gobject_class = (GObjectClass*) klass;
378 modest_window_class = (ModestWindowClass*) klass;
380 parent_class = g_type_class_peek_parent (klass);
381 gobject_class->finalize = modest_msg_edit_window_finalize;
383 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
384 modest_window_class->save_state_func = save_state;
385 modest_window_class->disconnect_signals_func = modest_msg_edit_window_disconnect_signals;
387 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
391 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
393 ModestMsgEditWindowPrivate *priv;
394 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
396 priv->msg_body = NULL;
397 priv->from_field = NULL;
398 priv->to_field = NULL;
399 priv->cc_field = NULL;
400 priv->bcc_field = NULL;
401 priv->subject_field = NULL;
402 priv->attachments = TNY_LIST (tny_simple_list_new ());
403 priv->images = TNY_LIST (tny_simple_list_new ());
404 priv->images_size = 0;
405 priv->images_count = 0;
408 priv->cc_caption = NULL;
409 priv->bcc_caption = NULL;
410 priv->update_caption_visibility = FALSE;
412 priv->priority_flags = 0;
414 priv->find_toolbar = NULL;
415 priv->last_search = NULL;
417 priv->draft_msg = NULL;
418 priv->outbox_msg = NULL;
419 priv->msg_uid = NULL;
421 priv->can_undo = FALSE;
422 priv->can_redo = FALSE;
423 priv->clipboard_change_handler_id = 0;
424 priv->default_clipboard_change_handler_id = 0;
425 priv->account_removed_handler_id = 0;
426 priv->clipboard_owner_idle = 0;
427 priv->clipboard_text = NULL;
430 priv->scroll_drag_timeout_id = 0;
431 priv->correct_scroll_idle = 0;
432 priv->last_upper = 0.0;
434 priv->font_dialog = NULL;
435 priv->app_menu = NULL;
437 priv->references = NULL;
438 priv->in_reply_to = NULL;
440 if (!is_wp_text_buffer_started) {
441 is_wp_text_buffer_started = TRUE;
442 wp_text_buffer_library_init ();
447 hildon_program_add_window (hildon_program_get_instance(),
452 multimailbox_get_default_mailbox (const gchar *account_name)
454 gchar *transport_account;
455 gchar *result = NULL;
457 transport_account = modest_account_mgr_get_server_account_name (modest_runtime_get_account_mgr (),
459 TNY_ACCOUNT_TYPE_TRANSPORT);
460 if (transport_account) {
462 ModestProtocolRegistry *registry;
464 registry = modest_runtime_get_protocol_registry ();
466 proto = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), transport_account,
467 MODEST_ACCOUNT_PROTO, TRUE);
469 ModestProtocol *protocol =
470 modest_protocol_registry_get_protocol_by_name (registry,
471 MODEST_PROTOCOL_REGISTRY_TRANSPORT_PROTOCOLS,
473 if (MODEST_ACCOUNT_PROTOCOL (protocol)) {
474 ModestPairList *pair_list;
476 pair_list = modest_account_protocol_get_from_list (MODEST_ACCOUNT_PROTOCOL (protocol),
479 ModestPair *pair = (ModestPair *) pair_list->data;
480 result = g_strdup ((const gchar *) pair->first);
481 modest_pair_list_free (pair_list);
492 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
494 static ModestPairList*
495 get_transports (void)
497 GSList *transports = NULL;
499 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
500 GSList *accounts = modest_account_mgr_account_names (account_mgr,
501 TRUE /* only enabled accounts. */);
503 GSList *cursor = accounts;
505 gchar *account_name = cursor->data;
508 gchar *transport_account;
509 gboolean multi_mailbox = FALSE;
510 ModestProtocol *protocol = NULL;
512 if (modest_account_mgr_account_is_multimailbox (account_mgr, account_name, &protocol)) {
514 transport_account = modest_account_mgr_get_server_account_name
515 (modest_runtime_get_account_mgr (),
517 TNY_ACCOUNT_TYPE_TRANSPORT);
518 if (protocol && MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
519 ModestPairList *pair_list;
520 pair_list = modest_account_protocol_get_from_list (MODEST_ACCOUNT_PROTOCOL (protocol),
523 transports = g_slist_concat (transports, pair_list);
524 multi_mailbox = TRUE;
529 if (!multi_mailbox) {
530 gchar *from_string = NULL;
532 from_string = modest_account_mgr_get_from_string (account_mgr,
534 if (from_string && account_name) {
535 gchar *name = account_name;
536 ModestPair *pair = modest_pair_new ((gpointer) name,
537 (gpointer) from_string , TRUE);
538 transports = g_slist_prepend (transports, pair);
543 cursor = cursor->next;
545 g_slist_free (accounts); /* only free the accounts, not the elements,
546 * because they are used in the pairlist */
550 static void window_focus (GtkWindow *window,
554 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
558 scroll_drag_timeout (gpointer userdata)
560 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
561 ModestMsgEditWindowPrivate *priv;
563 /* It could happen that the window was already closed */
564 if (!GTK_WIDGET_VISIBLE (win))
567 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
569 correct_scroll_without_drag_check (win, TRUE);
571 priv->scroll_drag_timeout_id = 0;
577 correct_scroll_without_drag_check_idle (gpointer userdata)
579 ModestMsgEditWindow *w = (ModestMsgEditWindow *) userdata;
580 ModestMsgEditWindowPrivate *priv;
582 GdkRectangle rectangle;
583 gint offset_min, offset_max;
587 /* It could happen that the window was already closed */
588 if (!GTK_WIDGET_VISIBLE (w))
591 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
593 insert = gtk_text_buffer_get_insert (priv->text_buffer);
594 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
596 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
597 offset_min = priv->msg_body->allocation.y + rectangle.y;
598 offset_max = offset_min + rectangle.height;
600 vadj = hildon_pannable_area_get_vadjustment (HILDON_PANNABLE_AREA (priv->pannable));
601 offset_min = MAX (offset_min - 48, 0);
602 offset_max = MIN (offset_max + 48, vadj->upper);
604 gtk_adjustment_clamp_page (vadj, (gdouble) offset_min, (gdouble) offset_max);
606 priv->correct_scroll_idle = 0;
611 correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused)
613 ModestMsgEditWindowPrivate *priv;
615 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
617 if (only_if_focused && !gtk_widget_is_focus (priv->msg_body))
620 if (priv->correct_scroll_idle > 0) {
624 priv->correct_scroll_idle = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
625 (GSourceFunc) correct_scroll_without_drag_check_idle,
631 correct_scroll (ModestMsgEditWindow *w)
633 ModestMsgEditWindowPrivate *priv;
635 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
636 if (gtk_grab_get_current () == priv->msg_body) {
637 if (priv->scroll_drag_timeout_id == 0) {
638 priv->scroll_drag_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
640 (GSourceFunc) scroll_drag_timeout,
647 correct_scroll_without_drag_check (w, TRUE);
651 text_buffer_end_user_action (GtkTextBuffer *buffer,
652 ModestMsgEditWindow *userdata)
655 correct_scroll (userdata);
659 text_buffer_mark_set (GtkTextBuffer *buffer,
662 ModestMsgEditWindow *userdata)
664 gtk_text_buffer_begin_user_action (buffer);
665 gtk_text_buffer_end_user_action (buffer);
669 cut_clipboard_check (GtkTextView *text_view,
672 GtkTextBuffer *buffer;
674 buffer = gtk_text_view_get_buffer (text_view);
675 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
676 g_signal_stop_emission_by_name ((gpointer )text_view, "cut-clipboard");
681 copy_clipboard_check (GtkTextView *text_view,
684 GtkTextBuffer *buffer;
686 buffer = gtk_text_view_get_buffer (text_view);
687 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
688 g_signal_stop_emission_by_name ((gpointer )text_view, "copy-clipboard");
693 attachment_deleted (ModestAttachmentsView *attachments_view,
696 modest_msg_edit_window_remove_attachments (MODEST_MSG_EDIT_WINDOW (user_data),
701 connect_signals (ModestMsgEditWindow *obj)
703 ModestMsgEditWindowPrivate *priv;
705 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
707 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
708 G_CALLBACK (text_buffer_refresh_attributes), obj);
709 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
710 G_CALLBACK (text_buffer_can_undo), obj);
711 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
712 G_CALLBACK (text_buffer_can_redo), obj);
713 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
714 G_CALLBACK (body_changed), obj);
715 g_signal_connect (G_OBJECT (priv->text_buffer), "modified-changed",
716 G_CALLBACK (body_changed), obj);
717 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
718 G_CALLBACK (text_buffer_end_user_action), obj);
719 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
720 G_CALLBACK (text_buffer_mark_set), obj);
721 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
722 G_CALLBACK (text_buffer_apply_tag), obj);
723 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
724 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
725 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
726 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
727 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
728 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
730 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
731 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
732 g_signal_connect (G_OBJECT (priv->from_field), "value-changed",
733 G_CALLBACK (from_field_changed), obj);
735 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
736 G_CALLBACK (msg_body_focus), obj);
737 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
738 G_CALLBACK (msg_body_focus), obj);
739 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
740 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
741 "changed", G_CALLBACK (recpt_field_changed), obj);
742 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
743 "changed", G_CALLBACK (recpt_field_changed), obj);
744 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
745 "changed", G_CALLBACK (recpt_field_changed), obj);
746 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
747 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
748 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
750 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
751 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
753 priv->clipboard_change_handler_id =
754 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
755 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
756 priv->default_clipboard_change_handler_id =
757 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
758 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
760 g_signal_connect (G_OBJECT (priv->msg_body), "cut-clipboard", G_CALLBACK (cut_clipboard_check), NULL);
761 g_signal_connect (G_OBJECT (priv->msg_body), "copy-clipboard", G_CALLBACK (copy_clipboard_check), NULL);
762 g_signal_connect (G_OBJECT (priv->attachments_view), "delete", G_CALLBACK (attachment_deleted), obj);
766 init_wp_text_view_style ()
768 static gboolean initialized = FALSE;
771 gtk_rc_parse_string ("class \"WPTextView\" style \"fremantle-textview\"");
777 init_window (ModestMsgEditWindow *obj)
779 GtkWidget *to_caption, *subject_caption;
780 GtkWidget *main_vbox;
781 GtkWidget *add_attachment_align;
782 ModestMsgEditWindowPrivate *priv;
783 GtkActionGroup *action_group;
784 ModestWindowPrivate *parent_priv;
785 GdkPixbuf *window_icon = NULL;
786 GError *error = NULL;
788 GtkSizeGroup *title_size_group;
789 GtkSizeGroup *value_size_group;
790 GtkWidget *attachment_icon;
791 GtkWidget *window_box;
792 GtkWidget *window_align;
793 #if (GTK_MINOR_VERSION >= 10)
794 GdkAtom deserialize_type;
797 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
798 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
800 parent_priv->ui_manager = gtk_ui_manager_new();
801 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
802 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
804 /* Add common actions */
805 gtk_action_group_add_actions (action_group,
806 modest_msg_edit_action_entries,
807 G_N_ELEMENTS (modest_msg_edit_action_entries),
809 gtk_action_group_add_actions (action_group,
810 hildon2_msg_edit_action_entries,
811 G_N_ELEMENTS (hildon2_msg_edit_action_entries),
813 gtk_action_group_add_toggle_actions (action_group,
814 modest_msg_edit_toggle_action_entries,
815 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
817 gtk_action_group_add_radio_actions (action_group,
818 modest_msg_edit_alignment_radio_action_entries,
819 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
821 G_CALLBACK (modest_ui_actions_on_change_justify),
823 gtk_action_group_add_radio_actions (action_group,
824 modest_msg_edit_priority_action_entries,
825 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
827 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
829 gtk_action_group_add_radio_actions (action_group,
830 modest_msg_edit_file_format_action_entries,
831 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
832 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
833 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
835 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
836 g_object_unref (action_group);
838 /* Load the UI definition */
839 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
842 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
843 g_clear_error (&error);
846 /* Add accelerators */
847 gtk_window_add_accel_group (GTK_WINDOW (obj),
848 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
850 parent_priv->menubar = NULL;
852 title_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
853 value_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
855 /* Note: This ModestPairList* must exist for as long as the picker
856 * that uses it, because the ModestSelectorPicker uses the ID opaquely,
857 * so it can't know how to manage its memory. */
858 priv->from_field = modest_selector_picker_new (MODEST_EDITABLE_SIZE,
859 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
861 modest_maemo_utils_set_hbutton_layout (title_size_group, value_size_group,
862 _("mail_va_from"), priv->from_field);
864 priv->to_field = modest_recpt_editor_new ();
865 priv->cc_field = modest_recpt_editor_new ();
866 priv->bcc_field = modest_recpt_editor_new ();
867 priv->subject_box = gtk_hbox_new (FALSE, MODEST_MARGIN_NONE);
868 priv->priority_icon = gtk_image_new ();
869 gtk_box_pack_start (GTK_BOX (priv->subject_box), priv->priority_icon, FALSE, FALSE, 0);
870 priv->subject_field = hildon_entry_new (MODEST_EDITABLE_SIZE);
871 gtk_entry_set_max_length (GTK_ENTRY (priv->subject_field) ,SUBJECT_MAX_LENGTH);
872 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
873 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
874 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
875 gtk_box_pack_start (GTK_BOX (priv->subject_box), priv->subject_field, TRUE, TRUE, 0);
876 priv->add_attachment_button = hildon_button_new (MODEST_EDITABLE_SIZE, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
877 gtk_widget_set_size_request (priv->add_attachment_button, ATTACHMENT_BUTTON_WIDTH, -1);
878 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
879 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
880 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, HILDON_ICON_SIZE_FINGER);
881 hildon_button_set_image (HILDON_BUTTON (priv->add_attachment_button), attachment_icon);
882 add_attachment_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
883 gtk_alignment_set_padding (GTK_ALIGNMENT (add_attachment_align), 0, 0, MODEST_MARGIN_DEFAULT, 0);
884 gtk_container_add (GTK_CONTAINER (add_attachment_align), priv->add_attachment_button);
885 gtk_box_pack_start (GTK_BOX (priv->subject_box), add_attachment_align, FALSE, FALSE, 0);
886 priv->attachments_view = modest_attachments_view_new (NULL);
887 modest_attachments_view_set_style (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
888 MODEST_ATTACHMENTS_VIEW_STYLE_NO_FOCUS);
890 priv->header_box = gtk_vbox_new (FALSE, 0);
892 to_caption = modest_maemo_utils_create_captioned_with_size_type
893 (title_size_group, value_size_group,
894 _("mail_va_to"), FALSE, priv->to_field,
895 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
896 priv->cc_caption = modest_maemo_utils_create_captioned_with_size_type
897 (title_size_group, value_size_group,
898 _("mail_va_cc"), FALSE, priv->cc_field,
899 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
900 priv->bcc_caption = modest_maemo_utils_create_captioned_with_size_type
901 (title_size_group, value_size_group,
902 _("mail_va_hotfix1"), FALSE, priv->bcc_field,
903 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
904 subject_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
905 _("mail_va_subject"), FALSE, priv->subject_box);
906 priv->attachments_caption = modest_maemo_utils_create_captioned_with_size_type (title_size_group, value_size_group,
907 _("mail_va_attachment"),
909 priv->attachments_view,
910 HILDON_SIZE_AUTO_WIDTH |
911 HILDON_SIZE_AUTO_HEIGHT);
912 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), value_size_group); */
913 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), value_size_group); */
914 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), value_size_group); */
915 g_object_unref (title_size_group);
916 g_object_unref (value_size_group);
918 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->from_field, FALSE, FALSE, 0);
919 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
920 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
921 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
922 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
923 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
924 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
926 init_wp_text_view_style ();
928 priv->msg_body = modest_wp_text_view_new ();
931 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
932 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
933 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
934 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
935 #if (GTK_MINOR_VERSION >= 10)
936 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), NULL);
937 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
939 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
940 deserialize_type, TRUE);
942 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
944 priv->find_toolbar = hildon_find_toolbar_new (NULL);
945 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
947 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
949 priv->pannable = hildon_pannable_area_new ();
951 g_object_set (G_OBJECT (priv->pannable), "hscrollbar-policy", GTK_POLICY_NEVER, NULL);
953 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
954 window_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
955 gtk_alignment_set_padding (GTK_ALIGNMENT (window_align), 0, 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DEFAULT);
957 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
958 gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 0);
959 gtk_container_add (GTK_CONTAINER (window_align), main_vbox);
961 hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA (priv->pannable), window_align);
962 gtk_widget_show_all (GTK_WIDGET(priv->pannable));
964 window_box = gtk_vbox_new (FALSE, 0);
965 gtk_container_add (GTK_CONTAINER(obj), window_box);
967 gtk_box_pack_start (GTK_BOX (window_box), priv->pannable, TRUE, TRUE, 0);
969 /* Set window icon */
970 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
972 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
973 g_object_unref (window_icon);
978 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
980 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
982 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
983 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
984 priv->clipboard_change_handler_id))
985 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
986 priv->clipboard_change_handler_id);
987 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
988 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
989 priv->default_clipboard_change_handler_id))
990 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
991 priv->default_clipboard_change_handler_id);
993 if (priv->account_removed_handler_id &&
994 g_signal_handler_is_connected (modest_runtime_get_account_store (),
995 priv->account_removed_handler_id))
996 g_signal_handler_disconnect(modest_runtime_get_account_store (),
997 priv->account_removed_handler_id);
1001 modest_msg_edit_window_finalize (GObject *obj)
1003 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1005 /* Sanity check: shouldn't be needed, the window mgr should
1006 call this function before */
1007 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
1009 if (priv->font_dialog != NULL) {
1010 gtk_dialog_response (GTK_DIALOG (priv->font_dialog), GTK_RESPONSE_NONE);
1013 if (priv->clipboard_text != NULL) {
1014 g_free (priv->clipboard_text);
1015 priv->clipboard_text = NULL;
1018 if (priv->draft_msg != NULL) {
1019 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
1020 if (TNY_IS_HEADER (header)) {
1021 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1022 modest_window_mgr_unregister_header (mgr, header);
1024 g_object_unref (priv->draft_msg);
1025 priv->draft_msg = NULL;
1027 if (priv->outbox_msg != NULL) {
1028 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
1029 if (TNY_IS_HEADER (header)) {
1030 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1031 modest_window_mgr_unregister_header (mgr, header);
1033 g_object_unref (priv->outbox_msg);
1034 priv->outbox_msg = NULL;
1036 if (priv->correct_scroll_idle > 0) {
1037 g_source_remove (priv->correct_scroll_idle);
1038 priv->correct_scroll_idle = 0;
1040 if (priv->scroll_drag_timeout_id > 0) {
1041 g_source_remove (priv->scroll_drag_timeout_id);
1042 priv->scroll_drag_timeout_id = 0;
1044 if (priv->clipboard_owner_idle > 0) {
1045 g_source_remove (priv->clipboard_owner_idle);
1046 priv->clipboard_owner_idle = 0;
1048 if (priv->original_account_name)
1049 g_free (priv->original_account_name);
1050 if (priv->original_mailbox)
1051 g_free (priv->original_mailbox);
1052 g_free (priv->msg_uid);
1053 g_free (priv->last_search);
1054 g_free (priv->references);
1055 g_free (priv->in_reply_to);
1056 g_object_unref (priv->faces_model);
1057 g_object_unref (priv->sizes_model);
1058 g_object_unref (priv->attachments);
1059 g_object_unref (priv->images);
1061 /* This had to stay alive for as long as the picker that used it: */
1062 modest_pair_list_free (priv->from_field_protos);
1064 G_OBJECT_CLASS(parent_class)->finalize (obj);
1068 pixbuf_size_prepared (GdkPixbufLoader *loader,
1071 ModestMsgEditWindow *self)
1073 gint new_height, new_width;
1076 new_height = height;
1080 if (width > IMAGE_MAX_WIDTH) {
1081 new_height = height * IMAGE_MAX_WIDTH / width;
1082 new_width = IMAGE_MAX_WIDTH;
1085 gdk_pixbuf_loader_set_size (loader, new_width, new_height);
1089 pixbuf_from_stream (TnyStream *stream,
1090 const gchar *mime_type,
1091 guint64 *stream_size,
1092 ModestMsgEditWindow *self)
1094 GdkPixbufLoader *loader;
1097 GError *error = NULL;
1101 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1103 if (loader == NULL) {
1108 g_signal_connect (G_OBJECT (loader), "size-prepared", G_CALLBACK (pixbuf_size_prepared), self);
1110 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), TRUE);
1112 tny_stream_reset (TNY_STREAM (stream));
1113 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1114 unsigned char read_buffer[128];
1116 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1118 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, &error)) {
1121 /* Allow some UI responsiveness */
1122 while (gtk_events_pending ())
1123 gtk_main_iteration ();
1125 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), FALSE);
1127 gdk_pixbuf_loader_close (loader, &error);
1130 g_error_free (error);
1131 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1133 g_object_ref (pixbuf);
1134 g_object_unref (loader);
1139 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1140 GdkPixbuf *new_pixbuf;
1142 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1143 gdk_pixbuf_get_width (pixbuf);
1144 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1145 g_object_unref (pixbuf);
1146 pixbuf = new_pixbuf;
1150 *stream_size = size;
1156 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1158 ModestMsgEditWindowPrivate *priv;
1161 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1163 g_object_ref (self);
1164 for (iter = tny_list_create_iterator (attachments);
1165 !tny_iterator_is_done (iter);
1166 tny_iterator_next (iter)) {
1167 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1168 const gchar *cid = tny_mime_part_get_content_id (part);
1169 const gchar *mime_type = tny_mime_part_get_content_type (part);
1170 if ((cid != NULL)&&(mime_type != NULL)) {
1171 guint64 stream_size;
1172 TnyStream *stream = tny_mime_part_get_decoded_stream (part);
1173 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size, self);
1176 g_object_unref (stream);
1178 if (pixbuf != NULL) {
1179 priv->images_count ++;
1180 priv->images_size += stream_size;
1181 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1182 g_object_unref (pixbuf);
1185 g_object_unref (part);
1187 g_object_unref (iter);
1188 g_object_unref (self);
1192 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1194 TnyMimePart *parent = NULL;
1195 const gchar *content_type = NULL;
1196 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1198 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1200 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1201 parent = g_object_ref (msg);
1202 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1203 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1206 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1207 iter = tny_list_create_iterator (parts);
1208 while (!tny_iterator_is_done (iter)) {
1210 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1211 content_type = tny_mime_part_get_content_type (part);
1212 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1216 g_object_unref (part);
1218 tny_iterator_next (iter);
1220 g_object_unref (iter);
1221 g_object_unref (parts);
1224 if (parent != NULL) {
1225 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1228 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1229 iter = tny_list_create_iterator (parts);
1230 while (!tny_iterator_is_done (iter)) {
1232 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1233 content_type = tny_mime_part_get_content_type (part);
1234 if (content_type && g_str_has_prefix (content_type, "image/")) {
1235 tny_list_prepend (priv->images, (GObject *) part);
1237 g_object_unref (part);
1238 tny_iterator_next (iter);
1240 g_object_unref (iter);
1241 g_object_unref (parts);
1242 g_object_unref (parent);
1247 update_next_cid (ModestMsgEditWindow *self, TnyList *attachments)
1250 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1252 for (iter = tny_list_create_iterator (attachments) ;
1253 !tny_iterator_is_done (iter);
1254 tny_iterator_next (iter)) {
1255 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1256 const gchar *cid = tny_mime_part_get_content_id (part);
1258 char *invalid = NULL;
1259 gint int_cid = strtol (cid, &invalid, 10);
1260 if ((invalid != NULL) && (*invalid == '\0') && (int_cid >= priv->next_cid)) {
1261 priv->next_cid = int_cid + 1;
1264 g_object_unref (part);
1266 g_object_unref (iter);
1270 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1273 gchar *to, *cc, *bcc, *subject;
1275 ModestMsgEditWindowPrivate *priv;
1276 ModestWindowPrivate *parent_priv;
1278 TnyHeaderFlags priority_flags;
1279 TnyFolder *msg_folder;
1280 gboolean is_html = FALSE;
1281 gboolean field_view_set;
1283 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1284 g_return_if_fail (TNY_IS_MSG (msg));
1286 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1287 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1289 header = tny_msg_get_header (msg);
1290 to = tny_header_dup_to (header);
1291 cc = tny_header_dup_cc (header);
1292 bcc = tny_header_dup_bcc (header);
1293 subject = tny_header_dup_subject (header);
1295 modest_tny_msg_get_references (TNY_MSG (msg), NULL, &(priv->references), &(priv->in_reply_to));
1296 priority_flags = tny_header_get_priority (header);
1299 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1301 field_view_set = TRUE;
1303 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1304 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1305 gtk_widget_show (priv->cc_caption);
1306 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1307 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1308 gtk_widget_hide (priv->cc_caption);
1309 field_view_set = FALSE;
1311 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->cc_button), field_view_set);
1313 field_view_set = TRUE;
1315 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1316 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1317 gtk_widget_show (priv->bcc_caption);
1318 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1319 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1320 gtk_widget_hide (priv->bcc_caption);
1321 field_view_set = FALSE;
1323 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->bcc_button), field_view_set);
1327 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1328 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1331 update_window_title (self);
1333 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1334 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1336 if ((body == NULL)||(body[0] == '\0')) {
1338 body = modest_text_utils_convert_to_html ("");
1341 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1342 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1345 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1348 /* Add attachments to the view */
1349 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1350 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1351 if (tny_list_get_length (priv->attachments) == 0) {
1352 gtk_widget_hide (priv->attachments_caption);
1354 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1355 gtk_widget_show_all (priv->attachments_caption);
1357 get_related_images (self, msg);
1358 update_next_cid (self, priv->attachments);
1359 update_next_cid (self, priv->images);
1360 replace_with_images (self, priv->images);
1362 if (preserve_is_rich && !is_html) {
1363 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1364 /* Get the default format required from configuration */
1365 } else if (!preserve_is_rich && !modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1366 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1369 /* Set the default focus depending on having already a To: field or not */
1370 if ((!to)||(*to == '\0')) {
1371 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1373 gtk_widget_grab_focus (priv->msg_body);
1376 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1378 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1379 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1381 modest_msg_edit_window_set_modified (self, FALSE);
1383 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1384 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1385 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1386 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1388 if (priv->msg_uid) {
1389 g_free (priv->msg_uid);
1390 priv->msg_uid = NULL;
1393 /* we should set a reference to the incoming message if it is a draft */
1394 msg_folder = tny_msg_get_folder (msg);
1396 if (modest_tny_folder_is_local_folder (msg_folder)) {
1397 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1398 if (type == TNY_FOLDER_TYPE_INVALID)
1399 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1401 if (type == TNY_FOLDER_TYPE_DRAFTS)
1402 priv->draft_msg = g_object_ref(msg);
1403 if (type == TNY_FOLDER_TYPE_OUTBOX)
1404 priv->outbox_msg = g_object_ref(msg);
1405 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1407 g_object_unref (msg_folder);
1418 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1420 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1421 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1422 GtkWidget *placeholder;
1423 GtkWidget *tool_item;
1428 GtkWidget *sizes_menu;
1429 GtkWidget *fonts_menu;
1435 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1436 gtk_toolbar_set_show_arrow (GTK_TOOLBAR (parent_priv->toolbar), FALSE);
1437 gtk_toolbar_set_icon_size (GTK_TOOLBAR (parent_priv->toolbar), HILDON_ICON_SIZE_FINGER);
1438 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1440 /* Font color placeholder */
1441 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1442 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1445 priv->font_color_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1446 priv->font_color_button = hildon_color_button_new ();
1447 gtk_widget_set_size_request (priv->font_color_button, -1, 48);
1448 GTK_WIDGET_UNSET_FLAGS (priv->font_color_toolitem, GTK_CAN_FOCUS);
1449 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1450 gtk_container_add (GTK_CONTAINER (priv->font_color_toolitem), priv->font_color_button);
1451 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1452 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1453 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->font_color_toolitem), insert_index);
1454 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1456 G_CALLBACK (modest_msg_edit_window_color_button_change),
1459 /* Font size and face placeholder */
1460 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1461 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1463 tool_item = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
1464 priv->size_tool_button_label = gtk_label_new (NULL);
1465 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1466 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1467 size_text, "</span>", NULL);
1468 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1469 gtk_misc_set_alignment (GTK_MISC (priv->size_tool_button_label), 1.0, 0.5);
1471 hildon_helper_set_logical_font (priv->size_tool_button_label, "LargeSystemFont");
1472 hbox = gtk_hbox_new (MODEST_MARGIN_DEFAULT, FALSE);
1473 gtk_box_pack_start (GTK_BOX (hbox), priv->size_tool_button_label, TRUE, TRUE, 0);
1474 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1475 gtk_misc_set_alignment (GTK_MISC (arrow), 0.0, 0.5);
1476 gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
1477 gtk_widget_set_sensitive (arrow, FALSE);
1478 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), hbox);
1479 sizes_menu = gtk_menu_new ();
1480 priv->sizes_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
1481 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1484 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1485 gtk_list_store_append (GTK_LIST_STORE (priv->sizes_model), &iter);
1487 gtk_list_store_set (GTK_LIST_STORE (priv->sizes_model), &iter,
1491 if (wp_font_size[size_index] == 12)
1492 priv->current_size_index = size_index;
1496 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (font_size_clicked), window);
1497 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1498 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1499 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1500 priv->font_size_toolitem = tool_item;
1503 tool_item = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
1504 priv->font_tool_button_label = gtk_label_new (NULL);
1505 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1506 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1507 gtk_misc_set_alignment (GTK_MISC (priv->font_tool_button_label), 1.0, 0.5);
1509 hildon_helper_set_logical_font (priv->font_tool_button_label, "LargeSystemFont");
1510 hbox = gtk_hbox_new (MODEST_MARGIN_DEFAULT, FALSE);
1511 gtk_box_pack_start (GTK_BOX (hbox), priv->font_tool_button_label, TRUE, TRUE, 0);
1512 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1513 gtk_misc_set_alignment (GTK_MISC (arrow), 0.0, 0.5);
1514 gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
1515 gtk_widget_set_sensitive (arrow, FALSE);
1516 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), hbox);
1517 fonts_menu = gtk_menu_new ();
1518 priv->faces_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
1519 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1522 gtk_list_store_append (GTK_LIST_STORE (priv->faces_model), &iter);
1524 gtk_list_store_set (GTK_LIST_STORE (priv->faces_model), &iter,
1525 0, wp_get_font_name (font_index),
1528 if (font_index == DEFAULT_FONT)
1529 priv->current_face_index = font_index;
1531 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (font_face_clicked), window);
1532 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1533 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1534 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1535 priv->font_face_toolitem = tool_item;
1537 /* Set expand and homogeneous for remaining items */
1538 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1539 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1540 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1541 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1542 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1543 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1544 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1545 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1546 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1548 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1549 will not show the tool items added to the placeholders) */
1550 gtk_widget_show_all (parent_priv->toolbar);
1552 /* Set the no show all *after* showing all items. We do not
1553 want the toolbar to be shown with a show all because it
1554 could go agains the gconf setting regarding showing or not
1555 the toolbar of the editor window */
1556 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1562 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, const gchar *mailbox, gboolean preserve_is_rich)
1565 ModestWindowPrivate *parent_priv;
1566 ModestMsgEditWindowPrivate *priv;
1567 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1568 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1569 ModestWindowMgr *mgr = NULL;
1571 g_return_val_if_fail (msg, NULL);
1572 g_return_val_if_fail (account_name, NULL);
1574 mgr = modest_runtime_get_window_mgr ();
1576 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1578 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1579 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1581 /* Menubar. Update the state of some toggles */
1582 priv->from_field_protos = get_transports ();
1583 priv->original_mailbox = NULL;
1584 modest_selector_picker_set_pair_list (MODEST_SELECTOR_PICKER (priv->from_field), priv->from_field_protos);
1585 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1586 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1587 if (mailbox && modest_pair_list_find_by_first_as_string (priv->from_field_protos, mailbox)) {
1588 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) mailbox);
1589 priv->original_mailbox = g_strdup (mailbox);
1590 } else if (modest_account_mgr_account_is_multimailbox (modest_runtime_get_account_mgr (), account_name, NULL)) {
1591 /* We set the first mailbox as the active mailbox */
1592 priv->original_mailbox = multimailbox_get_default_mailbox (account_name);
1593 if (priv->original_mailbox != NULL)
1594 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field),
1595 (gpointer) priv->original_mailbox);
1597 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field),
1598 (gpointer) account_name);
1600 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1602 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1603 hildon_button_set_title (HILDON_BUTTON (priv->from_field),
1605 hildon_button_set_value (HILDON_BUTTON (priv->from_field),
1606 hildon_touch_selector_get_current_text
1607 (HILDON_TOUCH_SELECTOR (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (priv->from_field)))));
1608 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1609 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1612 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1614 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1616 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1617 modest_window_set_active_mailbox (MODEST_WINDOW(obj), priv->original_mailbox);
1619 priv->original_account_name = (account_name) ? g_strdup (account_name) : NULL;
1621 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1622 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1623 /* Add common dimming rules */
1624 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1625 modest_msg_edit_window_toolbar_dimming_entries,
1626 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1627 MODEST_WINDOW (obj));
1628 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_toolitem,
1629 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1630 MODEST_WINDOW (obj));
1631 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1632 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1633 MODEST_WINDOW (obj));
1634 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1635 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1636 MODEST_WINDOW (obj));
1637 /* Insert dimming rules group for this window */
1638 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1639 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1641 /* Setup app menu */
1642 setup_menu (MODEST_MSG_EDIT_WINDOW (obj));
1644 /* Checks the dimming rules */
1645 g_object_unref (toolbar_rules_group);
1646 g_object_unref (clipboard_rules_group);
1647 gtk_widget_hide (priv->priority_icon);
1648 gtk_widget_queue_resize (priv->subject_box);
1649 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1651 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1653 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1654 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1655 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1656 priv->update_caption_visibility = TRUE;
1658 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1660 /* Track account-removed signal, this window should be closed
1661 in the case we're creating a mail associated to the account
1663 priv->account_removed_handler_id =
1664 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1666 G_CALLBACK(on_account_removed),
1669 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (MODEST_MSG_EDIT_WINDOW (obj));
1671 return (ModestWindow*) obj;
1675 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1677 GString **string_buffer = (GString **) user_data;
1679 *string_buffer = g_string_append (*string_buffer, buffer);
1685 * @result: A new string which should be freed with g_free().
1688 get_formatted_data (ModestMsgEditWindow *edit_window)
1690 ModestMsgEditWindowPrivate *priv;
1691 GString *string_buffer = g_string_new ("");
1693 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1695 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1697 modest_text_utils_hyperlinkify (string_buffer);
1699 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1701 return g_string_free (string_buffer, FALSE);
1706 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1709 const gchar *account_name;
1710 ModestMsgEditWindowPrivate *priv;
1711 TnyIterator *att_iter;
1712 const gchar *picker_active_id;
1714 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1716 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1718 picker_active_id = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1719 g_return_val_if_fail (picker_active_id, NULL);
1720 account_name = modest_utils_get_account_name_from_recipient (picker_active_id, NULL);
1722 /* don't free these (except from) */
1723 data = g_slice_new0 (MsgData);
1724 data->from = g_strdup ((gchar *) modest_selector_picker_get_active_display_name (MODEST_SELECTOR_PICKER (priv->from_field)));
1725 data->account_name = g_strdup (account_name);
1726 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1727 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1728 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1729 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1730 data->references = g_strdup (priv->references);
1731 data->in_reply_to = g_strdup (priv->in_reply_to);
1732 if (priv->draft_msg) {
1733 data->draft_msg = g_object_ref (priv->draft_msg);
1734 } else if (priv->outbox_msg) {
1735 data->draft_msg = g_object_ref (priv->outbox_msg);
1737 data->draft_msg = NULL;
1740 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1742 gtk_text_buffer_get_bounds (buf, &b, &e);
1743 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1745 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1746 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1748 data->html_body = NULL;
1750 /* deep-copy the data */
1751 att_iter = tny_list_create_iterator (priv->attachments);
1752 data->attachments = NULL;
1753 while (!tny_iterator_is_done (att_iter)) {
1754 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1755 if (!(TNY_IS_MIME_PART(part))) {
1756 g_warning ("strange data in attachment list");
1757 g_object_unref (part);
1758 tny_iterator_next (att_iter);
1761 data->attachments = g_list_append (data->attachments,
1763 tny_iterator_next (att_iter);
1765 g_object_unref (att_iter);
1767 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1768 att_iter = tny_list_create_iterator (priv->images);
1769 data->images = NULL;
1770 while (!tny_iterator_is_done (att_iter)) {
1771 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1773 if (!(TNY_IS_MIME_PART(part))) {
1774 g_warning ("strange data in attachment list");
1775 g_object_unref (part);
1776 tny_iterator_next (att_iter);
1779 cid = tny_mime_part_get_content_id (part);
1781 gchar *image_tag_id;
1782 GtkTextTag *image_tag;
1784 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1785 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1786 g_free (image_tag_id);
1788 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1790 ((gtk_text_iter_has_tag (&iter, image_tag))||
1791 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1792 data->images = g_list_append (data->images,
1793 g_object_ref (part));
1795 g_object_unref (part);
1796 tny_iterator_next (att_iter);
1798 g_object_unref (att_iter);
1800 data->priority_flags = priv->priority_flags;
1807 unref_gobject (GObject *obj, gpointer data)
1809 if (!G_IS_OBJECT(obj))
1811 g_object_unref (obj);
1815 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1818 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1826 g_free (data->from);
1827 g_free (data->subject);
1828 g_free (data->plain_body);
1829 g_free (data->html_body);
1830 g_free (data->account_name);
1831 g_free (data->references);
1832 g_free (data->in_reply_to);
1834 if (data->draft_msg != NULL) {
1835 g_object_unref (data->draft_msg);
1836 data->draft_msg = NULL;
1839 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1840 g_list_free (data->attachments);
1841 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1842 g_list_free (data->images);
1844 g_slice_free (MsgData, data);
1848 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1850 guint64 *parts_size)
1852 ModestMsgEditWindowPrivate *priv;
1854 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1856 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1858 /* TODO: add images */
1859 *parts_size += priv->images_size;
1860 *parts_count += priv->images_count;
1865 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1868 ModestMsgEditWindowPrivate *priv = NULL;
1869 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1871 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1873 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1875 return MODEST_MSG_EDIT_FORMAT_HTML;
1877 return MODEST_MSG_EDIT_FORMAT_TEXT;
1881 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1882 ModestMsgEditFormat format)
1884 ModestMsgEditWindowPrivate *priv;
1886 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1887 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1890 case MODEST_MSG_EDIT_FORMAT_HTML:
1891 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1893 case MODEST_MSG_EDIT_FORMAT_TEXT:
1894 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1897 g_return_if_reached ();
1901 ModestMsgEditFormatState *
1902 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1904 ModestMsgEditFormatState *format_state = NULL;
1905 ModestMsgEditWindowPrivate *priv;
1906 WPTextBufferFormat *buffer_format;
1908 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1910 buffer_format = g_new0 (WPTextBufferFormat, 1);
1911 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1913 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1915 format_state = g_new0 (ModestMsgEditFormatState, 1);
1916 format_state->bold = buffer_format->bold&0x1;
1917 format_state->italics = buffer_format->italic&0x1;
1918 format_state->bullet = buffer_format->bullet&0x1;
1919 format_state->color = buffer_format->color;
1920 format_state->font_size = buffer_format->font_size;
1921 format_state->font_family = wp_get_font_name (buffer_format->font);
1922 format_state->justification = buffer_format->justification;
1923 g_free (buffer_format);
1925 return format_state;
1930 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1931 const ModestMsgEditFormatState *format_state)
1933 ModestMsgEditWindowPrivate *priv;
1934 WPTextBufferFormat *buffer_format;
1935 WPTextBufferFormat *current_format;
1937 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1938 g_return_if_fail (format_state != NULL);
1940 buffer_format = g_new0 (WPTextBufferFormat, 1);
1941 current_format = g_new0 (WPTextBufferFormat, 1);
1943 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1944 gtk_widget_grab_focus (priv->msg_body);
1945 buffer_format->bold = (format_state->bold != FALSE);
1946 buffer_format->italic = (format_state->italics != FALSE);
1947 buffer_format->color = format_state->color;
1948 buffer_format->font_size = format_state->font_size;
1949 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1950 buffer_format->justification = format_state->justification;
1951 buffer_format->bullet = format_state->bullet;
1953 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1955 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1956 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1957 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1958 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1959 buffer_format->cs.font = (buffer_format->font != current_format->font);
1960 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1961 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1963 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1964 if (buffer_format->cs.bold) {
1965 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1966 GINT_TO_POINTER (buffer_format->bold&0x1));
1968 if (buffer_format->cs.italic) {
1969 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1970 GINT_TO_POINTER (buffer_format->italic&0x1));
1972 if (buffer_format->cs.color) {
1973 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1974 GINT_TO_POINTER (&(buffer_format->color)));
1976 if (buffer_format->cs.font_size) {
1977 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1978 GINT_TO_POINTER (buffer_format->font_size));
1980 if (buffer_format->cs.justification) {
1981 switch (buffer_format->justification) {
1982 case GTK_JUSTIFY_LEFT:
1983 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1984 GINT_TO_POINTER(TRUE));
1986 case GTK_JUSTIFY_CENTER:
1987 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1988 GINT_TO_POINTER(TRUE));
1990 case GTK_JUSTIFY_RIGHT:
1991 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1992 GINT_TO_POINTER(TRUE));
1999 if (buffer_format->cs.font) {
2000 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2001 GINT_TO_POINTER (buffer_format->font));
2003 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
2004 if (buffer_format->cs.bullet) {
2005 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
2006 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
2008 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
2010 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
2012 g_free (buffer_format);
2013 g_free (current_format);
2015 /* Check dimming rules */
2016 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2017 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
2021 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
2023 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2025 ModestWindowPrivate *parent_priv;
2026 ModestMsgEditWindowPrivate *priv;
2028 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2029 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2031 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
2032 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu");
2033 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2034 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
2036 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatPlainTextMenu");
2037 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2038 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
2041 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2043 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2044 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
2046 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2047 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
2049 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
2050 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
2053 switch (buffer_format->justification)
2055 case GTK_JUSTIFY_LEFT:
2056 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2058 case GTK_JUSTIFY_CENTER:
2059 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2061 case GTK_JUSTIFY_RIGHT:
2062 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2069 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
2071 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
2072 G_CALLBACK (modest_msg_edit_window_color_button_change),
2074 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
2075 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
2076 G_CALLBACK (modest_msg_edit_window_color_button_change),
2079 if (priv->current_size_index != buffer_format->font_size) {
2083 path = gtk_tree_path_new_from_indices (buffer_format->font_size, -1);
2084 if (gtk_tree_model_get_iter (priv->sizes_model, &iter, path)) {
2088 priv->current_size_index = buffer_format->font_size;
2090 gtk_tree_model_get (priv->sizes_model, &iter, 0, &size_text, -1);
2091 markup = g_strconcat ("<span font_family='Sans'>",
2092 size_text, "</span>", NULL);
2094 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2098 gtk_tree_path_free (path);
2101 if (priv->current_face_index != buffer_format->font) {
2105 path = gtk_tree_path_new_from_indices (buffer_format->font, -1);
2106 if (gtk_tree_model_get_iter (priv->faces_model, &iter, path)) {
2110 priv->current_face_index = buffer_format->font;
2111 gtk_tree_model_get (priv->faces_model, &iter, 0, &face_name, -1);
2112 markup = g_strconcat ("<span font_family='", face_name, "'>Tt</span>", NULL);
2113 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2120 g_free (buffer_format);
2124 #ifdef MODEST_HILDON_VERSION_0
2126 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2129 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2130 ModestMsgEditWindowPrivate *priv;
2131 GtkWidget *dialog = NULL;
2133 GdkColor *new_color = NULL;
2135 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2136 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2138 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2139 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2140 g_free (buffer_format);
2142 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2143 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2144 if (new_color != NULL) {
2145 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2146 (gpointer) new_color);
2149 gtk_widget_destroy (dialog);
2154 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2157 ModestMsgEditWindowPrivate *priv;
2158 GtkWidget *dialog = NULL;
2160 GdkColor *old_color = NULL;
2161 const GdkColor *new_color = NULL;
2163 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2164 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2166 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2167 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2169 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2170 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2171 if (new_color != NULL)
2172 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2174 gtk_widget_destroy (dialog);
2180 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2183 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2184 ModestMsgEditWindowPrivate *priv;
2185 GtkWidget *dialog = NULL;
2187 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2188 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2190 dialog = hildon_color_chooser_new ();
2191 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2192 g_free (buffer_format);
2194 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2196 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2197 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2200 gtk_widget_destroy (dialog);
2205 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2208 ModestMsgEditWindowPrivate *priv;
2209 GtkWidget *dialog = NULL;
2210 GdkColor *old_color = NULL;
2212 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2213 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2215 dialog = hildon_color_chooser_new ();
2216 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2218 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2220 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2221 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2223 gtk_widget_destroy (dialog);
2226 #endif /*!MODEST_HILDON_VERSION_0*/
2231 create_stream_for_uri (const gchar* uri)
2236 TnyStream *result = NULL;
2238 GnomeVFSHandle *handle = NULL;
2239 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2240 if (test == GNOME_VFS_OK) {
2241 TnyStream *vfssstream = TNY_STREAM (tny_vfs_stream_new (handle));
2242 /* Streams over OBEX (Bluetooth) are not seekable but
2243 * we expect them to be (we might need to read them
2244 * several times). So if this is a Bluetooth URI just
2245 * read the whole file into memory (this is not a fast
2246 * protocol so we can assume that these files are not
2247 * going to be very big) */
2248 if ((g_ascii_strncasecmp (uri, "obex://", 7) == 0)||
2249 (g_ascii_strncasecmp (uri, "upnpav://", 9) == 0)) {
2250 TnyStream *memstream = tny_camel_mem_stream_new ();
2251 tny_stream_write_to_stream (vfssstream, memstream);
2252 g_object_unref (vfssstream);
2255 result = vfssstream;
2263 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2266 ModestMsgEditWindowPrivate *priv;
2267 GtkWidget *dialog = NULL;
2269 GSList *uris = NULL;
2270 GSList *uri_node = NULL;
2272 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2274 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2275 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2276 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2278 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2280 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2281 GTK_WINDOW (dialog), GTK_WINDOW (window));
2283 response = gtk_dialog_run (GTK_DIALOG (dialog));
2285 case GTK_RESPONSE_OK:
2287 gchar *current_folder;
2288 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2289 current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
2290 if (current_folder && current_folder != '\0') {
2292 modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_INSERT_IMAGE_PATH,
2293 current_folder, &err);
2295 g_debug ("Error storing latest used folder: %s", err->message);
2299 g_free (current_folder);
2305 gtk_widget_destroy (dialog);
2307 g_object_ref (window);
2308 /* The operation could take some time so allow the dialog to be closed */
2309 while (gtk_events_pending ())
2310 gtk_main_iteration ();
2312 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2314 GnomeVFSHandle *handle = NULL;
2315 GnomeVFSResult result;
2316 GtkTextIter position;
2317 GtkTextMark *insert_mark;
2319 uri = (const gchar *) uri_node->data;
2320 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2321 if (result == GNOME_VFS_OK) {
2323 GnomeVFSFileInfo *info;
2324 gchar *filename, *basename, *escaped_filename;
2325 TnyMimePart *mime_part;
2327 const gchar *mime_type = NULL;
2328 GnomeVFSURI *vfs_uri;
2329 guint64 stream_size;
2331 gnome_vfs_close (handle);
2332 vfs_uri = gnome_vfs_uri_new (uri);
2334 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2335 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2336 g_free (escaped_filename);
2337 gnome_vfs_uri_unref (vfs_uri);
2338 info = gnome_vfs_file_info_new ();
2340 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2341 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2343 mime_type = gnome_vfs_file_info_get_mime_type (info);
2345 mime_part = tny_platform_factory_new_mime_part
2346 (modest_runtime_get_platform_factory ());
2348 TnyStream *stream = create_stream_for_uri (uri);
2350 if (stream == NULL) {
2352 modest_platform_information_banner (NULL, NULL,
2353 _FM("sfil_ib_opening_not_allowed"));
2355 g_object_unref (mime_part);
2356 gnome_vfs_file_info_unref (info);
2360 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2362 content_id = g_strdup_printf ("%d", priv->next_cid);
2363 tny_mime_part_set_content_id (mime_part, content_id);
2364 g_free (content_id);
2367 basename = g_path_get_basename (filename);
2368 tny_mime_part_set_filename (mime_part, basename);
2371 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size, window);
2373 if (pixbuf != NULL) {
2374 priv->images_size += stream_size;
2375 priv->images_count ++;
2376 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2377 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2378 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position,
2379 tny_mime_part_get_content_id (mime_part), pixbuf);
2380 g_object_unref (pixbuf);
2382 tny_list_prepend (priv->images, (GObject *) mime_part);
2383 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2385 modest_platform_information_banner (NULL, NULL,
2386 _("mail_ib_file_operation_failed"));
2390 g_object_unref (mime_part);
2391 gnome_vfs_file_info_unref (info);
2395 g_object_unref (window);
2399 on_attach_file_response (GtkDialog *dialog,
2403 GSList *uris = NULL;
2405 GnomeVFSFileSize total_size, allowed_size;
2406 ModestMsgEditWindow *window;
2407 ModestMsgEditWindowPrivate *priv;
2412 case GTK_RESPONSE_OK:
2414 gchar *current_folder;
2416 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2417 current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
2418 if (current_folder && current_folder != '\0') {
2420 modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_ATTACH_FILE_PATH,
2421 current_folder, &err);
2423 g_debug ("Error storing latest used folder: %s", err->message);
2427 g_free (current_folder);
2434 window = MODEST_MSG_EDIT_WINDOW (user_data);
2435 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2437 /* allowed size is the maximum size - what's already there */
2438 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2439 &att_num, &att_size);
2440 allowed_size = MODEST_MAX_ATTACHMENT_SIZE - att_size;
2443 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2445 const gchar *uri = (const gchar *) uri_node->data;
2448 modest_msg_edit_window_attach_file_one (window, uri, allowed_size);
2450 if (total_size > allowed_size) {
2451 g_warning ("%s: total size: %u",
2452 __FUNCTION__, (unsigned int)total_size);
2455 allowed_size -= total_size;
2457 g_slist_foreach (uris, (GFunc) g_free, NULL);
2458 g_slist_free (uris);
2460 gtk_widget_destroy (GTK_WIDGET (dialog));
2464 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2466 GtkWidget *dialog = NULL;
2467 ModestMsgEditWindowPrivate *priv;
2470 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(window));
2472 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2474 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2477 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window),
2478 GTK_FILE_CHOOSER_ACTION_OPEN);
2479 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2480 conf_folder = modest_conf_get_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_ATTACH_FILE_PATH, NULL);
2481 if (conf_folder && conf_folder[0] != '\0') {
2482 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), conf_folder);
2485 /* Set the default folder to images folder */
2486 docs_folder = g_build_filename (g_getenv (MODEST_MAEMO_UTILS_MYDOCS_ENV),
2487 ".documents", NULL);
2488 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), docs_folder);
2489 g_free (docs_folder);
2491 g_free (conf_folder);
2492 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2493 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2494 GTK_WINDOW (dialog), GTK_WINDOW (window));
2496 /* Connect to response & show */
2497 g_signal_connect (dialog, "response",
2498 G_CALLBACK (on_attach_file_response), window);
2499 gtk_widget_show (dialog);
2504 modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window,
2506 GnomeVFSFileSize allowed_size)
2509 GnomeVFSHandle *handle = NULL;
2510 ModestMsgEditWindowPrivate *priv;
2511 GnomeVFSResult result;
2512 GnomeVFSFileSize size = 0;
2513 g_return_val_if_fail (window, 0);
2514 g_return_val_if_fail (uri, 0);
2516 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2518 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2519 if (result == GNOME_VFS_OK) {
2520 TnyMimePart *mime_part;
2522 const gchar *mime_type = NULL;
2524 gchar *escaped_filename;
2527 GnomeVFSFileInfo *info;
2528 GnomeVFSURI *vfs_uri;
2530 gnome_vfs_close (handle);
2531 vfs_uri = gnome_vfs_uri_new (uri);
2534 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2535 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2536 g_free (escaped_filename);
2537 gnome_vfs_uri_unref (vfs_uri);
2539 info = gnome_vfs_file_info_new ();
2541 if (gnome_vfs_get_file_info (uri,
2543 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2545 mime_type = gnome_vfs_file_info_get_mime_type (info);
2546 mime_part = tny_platform_factory_new_mime_part
2547 (modest_runtime_get_platform_factory ());
2549 /* try to get the attachment's size; this may fail for weird
2550 * file systems, like obex, upnp... */
2551 if (allowed_size != 0 &&
2552 info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
2554 if (size > allowed_size) {
2555 modest_platform_information_banner (NULL, NULL,
2556 _FM("sfil_ib_opening_not_allowed"));
2561 g_warning ("%s: could not get attachment size", __FUNCTION__);
2563 stream = create_stream_for_uri (uri);
2565 if (stream == NULL) {
2567 modest_platform_information_banner (NULL, NULL, _FM("sfil_ib_opening_not_allowed"));
2569 g_object_unref (mime_part);
2571 gnome_vfs_file_info_unref (info);
2575 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2576 g_object_unref (stream);
2578 content_id = g_strdup_printf ("%d", priv->next_cid);
2579 tny_mime_part_set_content_id (mime_part, content_id);
2580 g_free (content_id);
2583 basename = g_path_get_basename (filename);
2584 tny_mime_part_set_filename (mime_part, basename);
2587 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2588 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2590 info->size == 0, info->size);
2591 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2592 gtk_widget_show_all (priv->attachments_caption);
2593 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2595 g_object_unref (mime_part);
2596 gnome_vfs_file_info_unref (info);
2603 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2606 ModestMsgEditWindowPrivate *priv;
2609 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2610 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2612 if (att_list == NULL) {
2613 att_list = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2614 if (!modest_maemo_utils_select_attachments (GTK_WINDOW (window), att_list, TRUE)) {
2615 g_object_unref (att_list);
2620 g_object_ref (att_list);
2623 if (tny_list_get_length (att_list) == 0) {
2624 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2626 gboolean dialog_response;
2627 gchar *message = NULL;
2628 gchar *filename = NULL;
2630 if (tny_list_get_length (att_list) == 1) {
2632 iter = tny_list_create_iterator (att_list);
2633 part = (TnyMimePart *) tny_iterator_get_current (iter);
2634 g_object_unref (iter);
2635 if (TNY_IS_MSG (part)) {
2636 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2638 filename = tny_header_dup_subject (header);
2639 g_object_unref (header);
2641 if (filename == NULL) {
2642 filename = g_strdup (_("mail_va_no_subject"));
2645 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2647 g_object_unref (part);
2649 filename = g_strdup ("");
2651 message = g_strdup_printf (ngettext("emev_nc_delete_attachment",
2652 "emev_nc_delete_attachments",
2653 tny_list_get_length (att_list)), filename);
2656 dialog_response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
2660 if (dialog_response != GTK_RESPONSE_OK) {
2661 g_object_unref (att_list);
2665 for (iter = tny_list_create_iterator (att_list);
2666 !tny_iterator_is_done (iter);
2667 tny_iterator_next (iter)) {
2668 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2669 const gchar *att_id;
2670 tny_list_remove (priv->attachments, (GObject *) mime_part);
2672 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2674 if (tny_list_get_length (priv->attachments) == 0)
2675 gtk_widget_hide (priv->attachments_caption);
2676 att_id = tny_mime_part_get_content_id (mime_part);
2678 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2680 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2681 g_object_unref (mime_part);
2683 g_object_unref (iter);
2686 g_object_unref (att_list);
2688 /* if the last attachment has been removed, focus the Subject: field */
2689 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2690 gtk_widget_grab_focus (priv->subject_field);
2694 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2697 ModestMsgEditWindowPrivate *priv;
2698 GdkColor *new_color;
2699 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2701 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2702 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2705 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2707 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2709 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2711 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2716 font_size_clicked (GtkToolButton *button,
2717 ModestMsgEditWindow *window)
2719 ModestMsgEditWindowPrivate *priv;
2720 GtkWidget *selector, *dialog;
2722 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2724 selector = hildon_touch_selector_new ();
2725 hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector), priv->sizes_model, TRUE);
2726 hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, priv->current_size_index);
2728 dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
2729 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog), HILDON_TOUCH_SELECTOR (selector));
2730 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_font_size"));
2732 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2736 WPTextBufferFormat format;
2738 new_index = hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (selector), 0);
2740 memset (&format, 0, sizeof (format));
2741 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2743 format.cs.font_size = TRUE;
2744 format.cs.text_position = TRUE;
2745 format.cs.font = TRUE;
2746 format.font_size = new_index;
2747 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2749 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2750 GINT_TO_POINTER (new_index)))
2751 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2753 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2754 size_text = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector));
2755 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
2756 size_text, "</span>", NULL);
2758 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2762 gtk_widget_destroy (dialog);
2764 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2769 font_face_clicked (GtkToolButton *button,
2770 ModestMsgEditWindow *window)
2772 ModestMsgEditWindowPrivate *priv;
2773 GtkWidget *selector, *dialog;
2774 GtkCellRenderer *renderer;
2776 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2778 selector = hildon_touch_selector_new ();
2779 renderer = gtk_cell_renderer_text_new ();
2780 g_object_set (G_OBJECT (renderer), "alignment", PANGO_ALIGN_CENTER, "xalign", 0.5, NULL);
2781 hildon_touch_selector_append_column (HILDON_TOUCH_SELECTOR (selector), priv->faces_model,
2782 renderer, "family", 0, "text", 0, NULL);
2783 hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, priv->current_face_index);
2785 dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
2786 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog), HILDON_TOUCH_SELECTOR (selector));
2787 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_font_face"));
2789 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2790 gint new_font_index;
2794 new_font_index = hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (selector), 0);
2795 path = gtk_tree_path_new_from_indices (new_font_index, -1);
2796 if (gtk_tree_model_get_iter (priv->faces_model, &iter, path)) {
2800 gtk_tree_model_get (priv->faces_model, &iter, 0, &face_name, -1);
2802 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2803 GINT_TO_POINTER(new_font_index)))
2804 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2806 markup = g_strconcat ("<span font_family='", face_name, "'>Tt</span>", NULL);
2807 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2809 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2813 gtk_tree_path_free (path);
2816 gtk_widget_destroy (dialog);
2818 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2823 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2826 ModestMsgEditWindowPrivate *priv = NULL;
2827 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2829 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2830 if (!priv->update_caption_visibility)
2833 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2835 gtk_widget_show (priv->cc_caption);
2837 gtk_widget_hide (priv->cc_caption);
2839 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2843 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2846 ModestMsgEditWindowPrivate *priv = NULL;
2847 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2849 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2850 if (!priv->update_caption_visibility)
2853 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2855 gtk_widget_show (priv->bcc_caption);
2857 gtk_widget_hide (priv->bcc_caption);
2859 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2863 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2864 ModestRecptEditor *editor)
2866 ModestMsgEditWindowPrivate *priv;
2868 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2869 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2871 /* we check for low-mem; in that case, show a warning, and don't allow
2872 * for the addressbook
2874 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2877 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2879 if (editor == NULL) {
2880 GtkWidget *view_focus;
2881 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2883 /* This code should be kept in sync with ModestRecptEditor. The
2884 textview inside the recpt editor is the one that really gets the
2885 focus. As it's inside a scrolled window, and this one inside the
2886 hbox recpt editor inherits from, we'll need to go up in the
2887 hierarchy to know if the text view is part of the recpt editor
2888 or if it's a different text entry */
2890 if (gtk_widget_get_parent (view_focus)) {
2891 GtkWidget *first_parent;
2893 first_parent = gtk_widget_get_parent (view_focus);
2894 if (gtk_widget_get_parent (first_parent) &&
2895 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2896 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2901 editor = MODEST_RECPT_EDITOR (priv->to_field);
2905 modest_address_book_select_addresses (editor);
2910 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2912 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2914 modest_msg_edit_window_open_addressbook (window, NULL);
2918 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2919 gboolean show_toolbar)
2921 ModestWindowPrivate *parent_priv;
2923 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2924 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2926 /* We can not just use the code of
2927 modest_msg_edit_window_setup_toolbar because it has a
2928 mixture of both initialization and creation code. */
2930 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2932 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2936 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2937 TnyHeaderFlags priority_flags)
2939 ModestMsgEditWindowPrivate *priv;
2940 ModestWindowPrivate *parent_priv;
2942 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2944 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2945 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2947 if (priv->priority_flags != priority_flags) {
2948 GtkAction *priority_action = NULL;
2950 priv->priority_flags = priority_flags;
2952 switch (priority_flags) {
2953 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2954 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2955 MODEST_HEADER_ICON_HIGH,
2956 HILDON_ICON_SIZE_SMALL);
2957 gtk_widget_show (priv->priority_icon);
2958 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2959 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2961 case TNY_HEADER_FLAG_LOW_PRIORITY:
2962 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2963 MODEST_HEADER_ICON_LOW,
2964 HILDON_ICON_SIZE_SMALL);
2965 gtk_widget_show (priv->priority_icon);
2966 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2967 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2970 gtk_widget_hide (priv->priority_icon);
2971 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2972 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2975 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2976 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2978 gtk_widget_queue_resize (priv->subject_box);
2982 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2985 ModestMsgEditWindowPrivate *priv;
2986 ModestWindowPrivate *parent_priv;
2987 gint current_format;
2989 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2991 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2992 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2994 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2995 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2997 if (current_format != file_format) {
2998 switch (file_format) {
2999 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
3000 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
3001 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
3003 case MODEST_FILE_FORMAT_PLAIN_TEXT:
3007 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
3008 response = gtk_dialog_run (GTK_DIALOG (dialog));
3009 gtk_widget_destroy (dialog);
3010 if (response == GTK_RESPONSE_OK) {
3011 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
3013 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu"));
3014 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
3019 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3020 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3021 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
3026 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
3029 ModestMsgEditWindowPrivate *priv;
3030 WPTextBufferFormat oldfmt, fmt;
3031 gint old_position = 0;
3035 GdkColor *color = NULL;
3036 gboolean bold, bold_set, italic, italic_set;
3037 gboolean underline, underline_set;
3038 gboolean strikethrough, strikethrough_set;
3039 gboolean position_set;
3040 gboolean font_size_set, font_set, color_set;
3043 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3044 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3046 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
3047 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(),
3048 GTK_WINDOW(dialog), GTK_WINDOW (window));
3050 /* First we get the currently selected font information */
3051 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
3053 switch (oldfmt.text_position) {
3054 case TEXT_POSITION_NORMAL:
3057 case TEXT_POSITION_SUPERSCRIPT:
3065 g_object_set (G_OBJECT (dialog),
3066 "bold", oldfmt.bold != FALSE,
3067 "bold-set", !oldfmt.cs.bold,
3068 "underline", oldfmt.underline != FALSE,
3069 "underline-set", !oldfmt.cs.underline,
3070 "italic", oldfmt.italic != FALSE,
3071 "italic-set", !oldfmt.cs.italic,
3072 "strikethrough", oldfmt.strikethrough != FALSE,
3073 "strikethrough-set", !oldfmt.cs.strikethrough,
3074 "color", &oldfmt.color,
3075 "color-set", !oldfmt.cs.color,
3076 "size", wp_font_size[oldfmt.font_size],
3077 "size-set", !oldfmt.cs.font_size,
3078 "position", old_position,
3079 "position-set", !oldfmt.cs.text_position,
3080 "family", wp_get_font_name (oldfmt.font),
3081 "family-set", !oldfmt.cs.font,
3084 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
3085 GTK_WINDOW (dialog), GTK_WINDOW (window));
3086 gtk_widget_show_all (dialog);
3087 priv->font_dialog = dialog;
3088 response = gtk_dialog_run (GTK_DIALOG (dialog));
3089 priv->font_dialog = NULL;
3090 if (response == GTK_RESPONSE_OK) {
3092 g_object_get( dialog,
3094 "bold-set", &bold_set,
3095 "underline", &underline,
3096 "underline-set", &underline_set,
3098 "italic-set", &italic_set,
3099 "strikethrough", &strikethrough,
3100 "strikethrough-set", &strikethrough_set,
3102 "color-set", &color_set,
3104 "size-set", &font_size_set,
3105 "family", &font_name,
3106 "family-set", &font_set,
3107 "position", &position,
3108 "position-set", &position_set,
3113 if (response == GTK_RESPONSE_OK) {
3114 memset(&fmt, 0, sizeof(fmt));
3120 fmt.italic = italic;
3121 fmt.cs.italic = TRUE;
3123 if (underline_set) {
3124 fmt.underline = underline;
3125 fmt.cs.underline = TRUE;
3127 if (strikethrough_set) {
3128 fmt.strikethrough = strikethrough;
3129 fmt.cs.strikethrough = TRUE;
3134 ? TEXT_POSITION_NORMAL
3135 : ( ( position == 1 )
3136 ? TEXT_POSITION_SUPERSCRIPT
3137 : TEXT_POSITION_SUBSCRIPT );
3138 fmt.cs.text_position = TRUE;
3139 fmt.font_size = oldfmt.font_size;
3143 fmt.cs.color = TRUE;
3146 fmt.font = wp_get_font_index(font_name,
3151 if (font_size_set) {
3152 fmt.cs.font_size = TRUE;
3153 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
3155 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
3156 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
3158 gtk_widget_destroy (dialog);
3160 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
3164 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
3166 ModestMsgEditWindowPrivate *priv;
3168 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3169 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3171 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
3173 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3174 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3178 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
3180 ModestMsgEditWindowPrivate *priv;
3182 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3183 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3185 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
3187 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3188 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3193 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
3195 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3197 priv->can_undo = can_undo;
3201 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
3203 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3205 priv->can_redo = can_redo;
3209 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
3211 ModestMsgEditWindowPrivate *priv;
3212 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3213 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3215 return priv->can_undo;
3219 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
3221 ModestMsgEditWindowPrivate *priv;
3222 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3223 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3225 return priv->can_redo;
3230 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
3233 GtkTextIter match_start, match_end;
3235 if (image_id == NULL)
3238 gtk_text_buffer_get_start_iter (buffer, &iter);
3240 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
3241 GSList *tags = gtk_text_iter_get_tags (&match_start);
3243 for (node = tags; node != NULL; node = g_slist_next (node)) {
3244 GtkTextTag *tag = (GtkTextTag *) node->data;
3245 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
3246 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
3247 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
3249 offset = gtk_text_iter_get_offset (&match_start);
3250 gtk_text_buffer_delete (buffer, &match_start, &match_end);
3251 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
3255 gtk_text_iter_forward_char (&iter);
3260 message_is_empty (ModestMsgEditWindow *window)
3262 ModestMsgEditWindowPrivate *priv = NULL;
3264 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3265 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3267 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
3268 * so we can ignore markup.
3270 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
3273 count = gtk_text_buffer_get_char_count (buf);
3279 msg_body_focus (GtkWidget *focus,
3280 GdkEventFocus *event,
3284 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3285 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3286 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3291 recpt_field_changed (GtkTextBuffer *buffer,
3292 ModestMsgEditWindow *editor)
3294 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3295 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3299 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3301 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3302 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3306 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3309 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3310 GtkTextBuffer *buffer;
3312 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3313 gtk_text_buffer_set_modified (buffer, modified);
3314 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3315 gtk_text_buffer_set_modified (buffer, modified);
3316 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3317 gtk_text_buffer_set_modified (buffer, modified);
3318 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3322 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3324 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3325 const char *account_name;
3326 GtkTextBuffer *buffer;
3328 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3329 if (gtk_text_buffer_get_modified (buffer))
3331 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3332 if (gtk_text_buffer_get_modified (buffer))
3334 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3335 if (gtk_text_buffer_get_modified (buffer))
3337 if (gtk_text_buffer_get_modified (priv->text_buffer))
3340 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3341 if (priv->original_mailbox) {
3342 if (!account_name || strcmp (account_name, priv->original_mailbox))
3344 } else if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3355 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3357 ModestMsgEditWindowPrivate *priv = NULL;
3359 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3360 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3362 /* check if there's no recipient added */
3363 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3364 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3365 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3366 /* no recipient contents, then select contacts */
3367 modest_msg_edit_window_open_addressbook (window, NULL);
3371 g_object_ref (window);
3372 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3373 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3374 g_object_unref (window);
3377 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3378 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3379 g_object_unref (window);
3382 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3383 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3384 g_object_unref (window);
3388 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3389 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3390 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3391 g_object_unref (window);
3398 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3399 ModestMsgEditWindow *window)
3401 modest_msg_edit_window_offer_attach_file (window);
3405 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3407 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3409 return priv->clipboard_text;
3413 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3415 ModestMsgEditWindow *window)
3417 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3418 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3421 /* It could happen that the window was already closed */
3422 if (!GTK_WIDGET_VISIBLE (window))
3425 g_object_ref (window);
3426 text = gtk_clipboard_wait_for_text (selection_clipboard);
3428 if (priv->clipboard_text != NULL) {
3429 g_free (priv->clipboard_text);
3431 priv->clipboard_text = text;
3433 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3435 g_object_unref (window);
3438 static gboolean clipboard_owner_change_idle (gpointer userdata)
3440 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
3441 ModestMsgEditWindowPrivate *priv;
3443 gdk_threads_enter ();
3444 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3445 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3447 priv->clipboard_owner_idle = 0;
3448 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, window);
3449 gdk_threads_leave ();
3455 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window)
3457 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3458 if (priv->clipboard_owner_idle == 0) {
3459 priv->clipboard_owner_idle = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
3460 clipboard_owner_change_idle,
3461 g_object_ref (window),
3467 subject_field_move_cursor (GtkEntry *entry,
3468 GtkMovementStep step,
3473 /* It could happen that the window was already closed */
3474 if (!GTK_WIDGET_VISIBLE (window))
3477 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3481 update_window_title (ModestMsgEditWindow *window)
3483 ModestMsgEditWindowPrivate *priv = NULL;
3484 const gchar *subject;
3486 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3487 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3488 if (subject == NULL || subject[0] == '\0')
3489 subject = _("mail_va_new_email");
3491 gtk_window_set_title (GTK_WINDOW (window), subject);
3496 subject_field_changed (GtkEditable *editable,
3497 ModestMsgEditWindow *window)
3499 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3500 update_window_title (window);
3501 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3502 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3503 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3507 subject_field_insert_text (GtkEditable *editable,
3509 gint new_text_length,
3511 ModestMsgEditWindow *window)
3513 GString *result = g_string_new ("");
3515 gint result_len = 0;
3516 const gchar *entry_text = NULL;
3519 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3520 old_length = g_utf8_strlen (entry_text, -1);
3522 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3523 gunichar c = g_utf8_get_char_validated (current, 8);
3524 /* Invalid unichar, stop */
3530 result = g_string_append_unichar (result, c);
3534 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3535 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3538 /* Prevent endless recursion */
3539 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3540 g_signal_emit_by_name (editable, "insert-text",
3541 (gpointer) result->str, (gpointer) result->len,
3542 (gpointer) position, (gpointer) window);
3543 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3547 if (result_len + old_length > 1000) {
3548 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3549 _CS("ckdg_ib_maximum_characters_reached"));
3551 g_string_free (result, TRUE);
3555 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3558 ModestMsgEditWindowPrivate *priv = NULL;
3560 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3561 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3563 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3566 gtk_widget_show_all (priv->find_toolbar);
3567 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3569 gtk_widget_hide_all (priv->find_toolbar);
3570 gtk_widget_grab_focus (priv->msg_body);
3575 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3577 GtkTextIter *match_start,
3578 GtkTextIter *match_end)
3580 GtkTextIter end_iter;
3581 gchar *str_casefold;
3584 gchar *range_casefold;
3587 gboolean result = FALSE;
3594 gtk_text_iter_forward_to_end (&end_iter);
3596 str_casefold = g_utf8_casefold (str, -1);
3597 str_chars_n = strlen (str);
3599 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3600 range_casefold = g_utf8_casefold (range_text, -1);
3601 range_chars_n = strlen (range_casefold);
3603 if (range_chars_n < str_chars_n) {
3604 g_free (str_casefold);
3605 g_free (range_text);
3606 g_free (range_casefold);
3610 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3611 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3612 if (!g_utf8_collate (range_subtext, str_casefold)) {
3613 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3615 if (!gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3616 match_start, match_end, NULL)) {
3617 g_warning ("Matched string with collate, but not matched in model");
3619 g_free (found_text);
3621 g_free (range_subtext);
3625 g_free (str_casefold);
3626 g_free (range_text);
3627 g_free (range_casefold);
3634 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3635 ModestMsgEditWindow *window)
3637 gchar *current_search = NULL;
3638 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3640 GtkTextIter selection_start, selection_end;
3641 GtkTextIter match_start, match_end;
3642 gboolean continue_search = FALSE;
3644 if (message_is_empty (window)) {
3645 g_free (priv->last_search);
3646 priv->last_search = NULL;
3647 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3651 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3652 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3653 g_free (current_search);
3654 g_free (priv->last_search);
3655 priv->last_search = NULL;
3656 /* Information banner about empty search */
3657 hildon_banner_show_information (NULL, NULL, _CS("ecdg_ib_find_rep_enter_text"));
3661 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3662 continue_search = TRUE;
3664 g_free (priv->last_search);
3665 priv->last_search = g_strdup (current_search);
3668 if (continue_search) {
3669 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3670 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3671 &match_start, &match_end);
3673 hildon_banner_show_information (NULL, NULL, _HL("ckct_ib_find_search_complete"));
3675 GtkTextIter buffer_start;
3676 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3677 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3678 &match_start, &match_end);
3680 hildon_banner_show_information (NULL, NULL, _HL("ckct_ib_find_no_matches"));
3683 /* Mark as selected the string found in search */
3685 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3686 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3687 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3689 g_free (priv->last_search);
3690 priv->last_search = NULL;
3692 g_free (current_search);
3696 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3698 ModestMsgEditWindowPrivate *priv;
3700 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3705 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3708 ModestMsgEditWindowPrivate *priv;
3710 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3715 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3716 ModestMsgEditWindow *window)
3718 modest_msg_edit_window_toggle_find_toolbar (window, FALSE);
3722 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3725 ModestMsgEditWindowPrivate *priv;
3726 TnyHeader *header = NULL;
3728 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3729 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3731 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3733 if (priv->draft_msg != NULL) {
3734 g_object_unref (priv->draft_msg);
3737 if (draft != NULL) {
3738 g_object_ref (draft);
3739 header = tny_msg_get_header (draft);
3740 if (priv->msg_uid) {
3741 g_free (priv->msg_uid);
3742 priv->msg_uid = NULL;
3744 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3747 priv->draft_msg = draft;
3751 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3752 GtkTextIter *start, GtkTextIter *end,
3755 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3756 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3759 if (tag == NULL) return;
3760 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3761 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3762 replace_with_images (window, priv->images);
3767 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3770 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3772 g_return_if_fail (TNY_IS_MIME_PART (part));
3773 tny_list_prepend (priv->attachments, (GObject *) part);
3774 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3775 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3776 gtk_widget_show_all (priv->attachments_caption);
3777 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3781 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3783 ModestMsgEditWindowPrivate *priv;
3785 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3786 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3788 return priv->msg_uid;
3792 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3793 ModestMsgEditWindowWidgetType widget_type)
3795 ModestMsgEditWindowPrivate *priv;
3797 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3798 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3800 switch (widget_type) {
3801 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3802 return priv->msg_body;
3804 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3805 return priv->to_field;
3807 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3808 return priv->cc_field;
3810 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3811 return priv->bcc_field;
3813 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3814 return priv->subject_field;
3816 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3817 return priv->attachments_view;
3825 remove_tags (WPTextBuffer *buffer)
3827 GtkTextIter start, end;
3829 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3830 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3832 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3836 on_account_removed (TnyAccountStore *account_store,
3837 TnyAccount *account,
3840 /* Do nothing if it's a store account, because we use the
3841 transport to send the messages */
3842 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3843 const gchar *parent_acc = NULL;
3844 const gchar *our_acc = NULL;
3846 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3847 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3848 /* Close this window if I'm showing a message of the removed account */
3849 if (strcmp (parent_acc, our_acc) == 0)
3850 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3854 static void update_signature (ModestMsgEditWindow *self,
3855 const gchar *old_account,
3856 const gchar *new_account)
3858 ModestMsgEditWindowPrivate *priv;
3859 gboolean has_old_signature, has_new_signature;
3861 GtkTextIter match_start, match_end;
3862 ModestAccountMgr *mgr;
3864 gchar *full_signature;
3866 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
3868 gtk_text_buffer_begin_user_action (priv->text_buffer);
3870 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
3871 mgr = modest_runtime_get_account_mgr ();
3875 signature = modest_account_mgr_get_signature_from_recipient (mgr, old_account, &has_old_signature);
3876 if (has_old_signature) {
3877 full_signature = g_strconcat ("\n--\n", signature, NULL);
3878 if (gtk_text_iter_forward_search (&iter, full_signature, 0, &match_start, &match_end, NULL)) {
3879 gtk_text_buffer_delete (priv->text_buffer, &match_start, &match_end);
3881 } else if (gtk_text_iter_forward_search (&iter, _("mcen_ia_editor_original_message"), 0,
3882 &match_start, &match_end, NULL)) {
3885 g_free (full_signature);
3890 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3891 signature = modest_account_mgr_get_signature_from_recipient (mgr, new_account, &has_new_signature);
3892 if (has_new_signature) {
3893 full_signature = g_strconcat ("\n--\n", signature, NULL);
3894 gtk_text_buffer_insert (priv->text_buffer, &iter, full_signature, -1);
3895 g_free (full_signature);
3898 gtk_text_buffer_end_user_action (priv->text_buffer);
3902 from_field_changed (HildonPickerButton *button,
3903 ModestMsgEditWindow *self)
3905 ModestMsgEditWindowPrivate *priv;
3906 gchar *old_account, *new_account;
3908 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
3910 old_account = priv->last_from_account;
3911 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3912 new_account = priv->last_from_account;
3914 update_signature (self, old_account, new_account);
3918 typedef struct _MessageSettingsHelper {
3919 ModestMsgEditWindow *window;
3920 GSList *priority_group;
3921 GSList *format_group;
3922 GtkToggleButton *current_priority;
3923 GtkToggleButton *current_format;
3924 } MessageSettingsHelper;
3927 on_priority_toggle (GtkToggleButton *button,
3928 MessageSettingsHelper *helper)
3931 ModestMsgEditWindowPrivate *priv;
3933 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (helper->window);
3934 if (gtk_toggle_button_get_active (button)) {
3936 for (node = helper->priority_group; node != NULL; node = g_slist_next (node)) {
3937 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3938 if ((node_button != button) &&
3939 gtk_toggle_button_get_active (node_button)) {
3940 gtk_toggle_button_set_active (node_button, FALSE);
3943 helper->current_priority = button;
3945 gboolean found = FALSE;
3946 /* If no one is active, activate it again */
3947 for (node = helper->priority_group; node != NULL; node = g_slist_next (node)) {
3948 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3949 if (gtk_toggle_button_get_active (node_button)) {
3955 gtk_toggle_button_set_active (button, TRUE);
3961 on_format_toggle (GtkToggleButton *button,
3962 MessageSettingsHelper *helper)
3965 ModestMsgEditWindowPrivate *priv;
3967 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (helper->window);
3968 if (gtk_toggle_button_get_active (button)) {
3970 for (node = helper->format_group; node != NULL; node = g_slist_next (node)) {
3971 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3972 if ((node_button != button) &&
3973 gtk_toggle_button_get_active (node_button)) {
3974 gtk_toggle_button_set_active (node_button, FALSE);
3977 helper->current_format = button;
3979 gboolean found = FALSE;
3980 /* If no one is active, activate it again */
3981 for (node = helper->format_group; node != NULL; node = g_slist_next (node)) {
3982 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3983 if (gtk_toggle_button_get_active (node_button)) {
3989 gtk_toggle_button_set_active (button, TRUE);
3996 modest_msg_edit_window_show_msg_settings_dialog (ModestMsgEditWindow *window)
4001 GtkWidget *priority_hbox;
4002 GtkWidget *high_toggle, *medium_toggle, *low_toggle;
4003 GtkWidget *captioned;
4004 GtkSizeGroup *title_sizegroup, *value_sizegroup;
4005 GtkWidget *format_hbox;
4006 GtkWidget *html_toggle, *text_toggle;
4007 ModestMsgEditWindowPrivate *priv;
4008 MessageSettingsHelper helper = {0,};
4010 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4011 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
4012 helper.window = window;
4013 helper.priority_group = NULL;
4014 helper.format_group = NULL;
4016 title_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4017 value_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4019 dialog = gtk_dialog_new_with_buttons (_("mcen_me_message_settings"), NULL,
4020 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
4021 _HL("wdgt_bd_done"), GTK_RESPONSE_ACCEPT, NULL);
4022 vbox = gtk_vbox_new (FALSE, 0);
4023 align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
4024 gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE, 0);
4025 gtk_container_add (GTK_CONTAINER (align), vbox);
4026 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), align);
4027 gtk_widget_show (align);
4028 gtk_widget_show (vbox);
4030 /* Priority toggles */
4031 priority_hbox = gtk_hbox_new (TRUE, 0);
4032 high_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4033 gtk_button_set_label (GTK_BUTTON (high_toggle), _("mcen_me_editor_priority_high"));
4034 helper.priority_group = g_slist_prepend (helper.priority_group, high_toggle);
4035 g_object_set_data (G_OBJECT (high_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_HIGH_PRIORITY));
4036 medium_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4037 gtk_button_set_label (GTK_BUTTON (medium_toggle), _("mcen_me_editor_priority_normal"));
4038 helper.priority_group = g_slist_prepend (helper.priority_group, medium_toggle);
4039 g_object_set_data (G_OBJECT (medium_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_NORMAL_PRIORITY));
4040 low_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4041 gtk_button_set_label (GTK_BUTTON (low_toggle), _("mcen_me_editor_priority_low"));
4042 helper.priority_group = g_slist_prepend (helper.priority_group, low_toggle);
4043 g_object_set_data (G_OBJECT (low_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_LOW_PRIORITY));
4044 gtk_box_pack_start (GTK_BOX (priority_hbox), low_toggle, TRUE, TRUE, 0);
4045 gtk_box_pack_start (GTK_BOX (priority_hbox), medium_toggle, TRUE, TRUE, 0);
4046 gtk_box_pack_start (GTK_BOX (priority_hbox), high_toggle, TRUE, TRUE, 0);
4047 gtk_widget_show_all (priority_hbox);
4048 captioned = modest_maemo_utils_create_captioned (title_sizegroup, value_sizegroup,
4049 _("mcen_me_editor_message_priority"), FALSE, priority_hbox);
4050 gtk_widget_show (captioned);
4051 gtk_box_pack_start (GTK_BOX (vbox), captioned, FALSE, FALSE, 0);
4053 /* format toggles */
4054 format_hbox = gtk_hbox_new (TRUE, 0);
4055 html_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4056 gtk_button_set_label (GTK_BUTTON (html_toggle), _("mcen_me_editor_formatted_text"));
4057 helper.format_group = g_slist_prepend (helper.format_group, html_toggle);
4058 g_object_set_data (G_OBJECT (html_toggle), "format", GINT_TO_POINTER (MODEST_MSG_EDIT_FORMAT_HTML));
4059 g_object_set_data (G_OBJECT (html_toggle), "file-format", GINT_TO_POINTER (MODEST_FILE_FORMAT_FORMATTED_TEXT));
4060 text_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4061 gtk_button_set_label (GTK_BUTTON (text_toggle), _("mcen_me_editor_plain_text"));
4062 helper.format_group = g_slist_prepend (helper.format_group, text_toggle);
4063 g_object_set_data (G_OBJECT (text_toggle), "format", GINT_TO_POINTER (MODEST_MSG_EDIT_FORMAT_TEXT));
4064 g_object_set_data (G_OBJECT (text_toggle), "file-format", GINT_TO_POINTER (MODEST_FILE_FORMAT_PLAIN_TEXT));
4065 gtk_box_pack_start (GTK_BOX (format_hbox), html_toggle, TRUE, TRUE, 0);
4066 gtk_box_pack_start (GTK_BOX (format_hbox), text_toggle, TRUE, TRUE, 0);
4067 gtk_widget_show_all (format_hbox);
4068 gtk_widget_show (format_hbox);
4069 gtk_box_pack_start (GTK_BOX (vbox), format_hbox, FALSE, FALSE, 0);
4072 g_object_unref (title_sizegroup);
4073 g_object_unref (value_sizegroup);
4075 /* Set current values */
4076 switch (priv->priority_flags) {
4077 case TNY_HEADER_FLAG_HIGH_PRIORITY:
4078 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (high_toggle), TRUE);
4079 helper.current_priority = GTK_TOGGLE_BUTTON (high_toggle);
4081 case TNY_HEADER_FLAG_LOW_PRIORITY:
4082 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (low_toggle), TRUE);
4083 helper.current_priority = GTK_TOGGLE_BUTTON (low_toggle);
4086 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (medium_toggle), TRUE);
4087 helper.current_priority = GTK_TOGGLE_BUTTON (medium_toggle);
4091 switch (modest_msg_edit_window_get_format (window)) {
4092 case MODEST_MSG_EDIT_FORMAT_TEXT:
4093 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (text_toggle), TRUE);
4094 helper.current_format = GTK_TOGGLE_BUTTON (text_toggle);
4096 case MODEST_MSG_EDIT_FORMAT_HTML:
4098 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (html_toggle), TRUE);
4099 helper.current_format = GTK_TOGGLE_BUTTON (html_toggle);
4103 /* Signal connects */
4104 g_signal_connect (G_OBJECT (high_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4105 g_signal_connect (G_OBJECT (medium_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4106 g_signal_connect (G_OBJECT (low_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4107 g_signal_connect (G_OBJECT (html_toggle), "toggled", G_CALLBACK (on_format_toggle), &helper);
4108 g_signal_connect (G_OBJECT (text_toggle), "toggled", G_CALLBACK (on_format_toggle), &helper);
4110 /* Save settings if the user clicked on done */
4111 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
4112 TnyHeaderFlags flags;
4113 ModestMsgEditFormat old_format, new_format;
4115 /* Set priority flags */
4116 flags = (TnyHeaderFlags) g_object_get_data (G_OBJECT (helper.current_priority), "priority");
4117 if (priv->priority_flags != flags)
4118 modest_msg_edit_window_set_priority_flags (window, flags);
4120 /* Set edit format */
4121 old_format = modest_msg_edit_window_get_format (window);
4122 new_format = (ModestMsgEditFormat) g_object_get_data (G_OBJECT (helper.current_format), "format");
4123 if (old_format != new_format) {
4124 gint file_format = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (helper.current_format), "file-format"));
4125 modest_msg_edit_window_set_file_format (window, file_format);
4129 gtk_widget_destroy (dialog);
4130 g_slist_free (helper.priority_group);
4134 on_message_settings (GtkAction *action,
4135 ModestMsgEditWindow *window)
4137 modest_msg_edit_window_show_msg_settings_dialog (window);
4141 on_cc_button_toggled (HildonCheckButton *button,
4142 ModestMsgEditWindow *window)
4144 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
4146 modest_msg_edit_window_show_cc (MODEST_MSG_EDIT_WINDOW (window),
4147 hildon_check_button_get_active (button));
4151 on_bcc_button_toggled (HildonCheckButton *button,
4152 ModestMsgEditWindow *window)
4154 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
4156 modest_msg_edit_window_show_bcc (MODEST_MSG_EDIT_WINDOW (window),
4157 hildon_check_button_get_active (button));
4161 setup_menu (ModestMsgEditWindow *self)
4163 ModestMsgEditWindowPrivate *priv = NULL;
4165 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(self));
4167 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
4169 /* Settings menu buttons */
4170 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_editor_checknames"), NULL,
4171 APP_MENU_CALLBACK (modest_ui_actions_on_check_names),
4173 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_undo"), "<Ctrl>z",
4174 APP_MENU_CALLBACK (modest_ui_actions_on_undo),
4175 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_undo));
4177 priv->cc_button = hildon_check_button_new (0);
4178 gtk_button_set_label (GTK_BUTTON (priv->cc_button), _("mcen_me_editor_showcc"));
4179 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->cc_button),
4181 modest_hildon2_window_add_button_to_menu (MODEST_HILDON2_WINDOW (self), GTK_BUTTON (priv->cc_button),
4183 g_signal_connect (G_OBJECT (priv->cc_button), "toggled",
4184 G_CALLBACK (on_cc_button_toggled), (gpointer) self);
4185 priv->bcc_button = hildon_check_button_new (0);
4186 gtk_button_set_label (GTK_BUTTON (priv->bcc_button), _("mcen_me_editor_showbcc"));
4187 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->bcc_button),
4189 modest_hildon2_window_add_button_to_menu (MODEST_HILDON2_WINDOW (self), GTK_BUTTON (priv->bcc_button),
4191 g_signal_connect (G_OBJECT (priv->bcc_button), "toggled",
4192 G_CALLBACK (on_bcc_button_toggled), (gpointer) self);
4194 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_editor_attach_inlineimage"), NULL,
4195 APP_MENU_CALLBACK (modest_ui_actions_on_insert_image),
4196 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_set_style));
4197 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_remove_attachments"), NULL,
4198 APP_MENU_CALLBACK (modest_ui_actions_on_remove_attachments),
4199 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_editor_remove_attachment));
4200 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_message_settings"), NULL,
4201 APP_MENU_CALLBACK (on_message_settings),
4203 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_viewer_find"), "<Ctrl>f",
4204 APP_MENU_CALLBACK (modest_ui_actions_on_toggle_find_in_page),