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
95 #define MAX_FROM_VALUE 48
97 static gboolean is_wp_text_buffer_started = FALSE;
99 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
100 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
101 static void modest_msg_edit_window_finalize (GObject *obj);
103 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
104 static void body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
105 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
107 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
108 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
109 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
110 static void text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
111 GtkTextIter *start, GtkTextIter *end,
113 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
114 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
115 static void subject_field_insert_text (GtkEditable *editable,
117 gint new_text_length,
119 ModestMsgEditWindow *window);
120 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
122 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
124 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
125 ModestRecptEditor *editor);
126 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
127 ModestMsgEditWindow *window);
129 /* ModestWindow methods implementation */
130 static void modest_msg_edit_window_disconnect_signals (ModestWindow *window);
131 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
132 gboolean show_toolbar);
133 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
135 ModestMsgEditWindow *window);
136 static void modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window);
137 static void subject_field_move_cursor (GtkEntry *entry,
138 GtkMovementStep step,
142 static void update_window_title (ModestMsgEditWindow *window);
145 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
146 ModestMsgEditWindow *window);
147 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
148 ModestMsgEditWindow *window);
149 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
151 GtkTextIter *match_start,
152 GtkTextIter *match_end);
154 static void remove_tags (WPTextBuffer *buffer);
156 static void on_account_removed (TnyAccountStore *account_store,
160 static void init_window (ModestMsgEditWindow *obj);
162 gboolean scroll_drag_timeout (gpointer userdata);
163 static void correct_scroll (ModestMsgEditWindow *w);
164 static void correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused);
165 static void text_buffer_end_user_action (GtkTextBuffer *buffer,
166 ModestMsgEditWindow *userdata);
167 static void text_buffer_mark_set (GtkTextBuffer *buffer,
170 ModestMsgEditWindow *userdata);
171 static void on_message_settings (GtkAction *action,
172 ModestMsgEditWindow *window);
173 static void setup_menu (ModestMsgEditWindow *self);
175 static void from_field_changed (HildonPickerButton *button,
176 ModestMsgEditWindow *self);
177 static void font_size_clicked (GtkToolButton *button,
178 ModestMsgEditWindow *window);
179 static void font_face_clicked (GtkToolButton *button,
180 ModestMsgEditWindow *window);
181 static void update_signature (ModestMsgEditWindow *self,
182 const gchar *old_account,
183 const gchar *new_account);
184 static void DEBUG_BUFFER (WPTextBuffer *buffer)
188 g_message ("BEGIN BUFFER OF SIZE %d", gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (buffer)));
190 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
191 while (!gtk_text_iter_is_end (&iter)) {
192 GString *output = g_string_new ("");
193 GSList *toggled_tags;
196 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
197 g_string_append_printf (output, "%d: CLOSED [ ", gtk_text_iter_get_offset (&iter));
198 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
199 GtkTextTag *tag = (GtkTextTag *) node->data;
201 g_object_get (G_OBJECT (tag), "name", &name, NULL);
202 output = g_string_append (output, name);
203 g_string_append (output, " ");
205 output = g_string_append (output, "] OPENED [ ");
206 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
207 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
208 GtkTextTag *tag = (GtkTextTag *) node->data;
210 g_object_get (G_OBJECT (tag), "name", &name, NULL);
211 output = g_string_append (output, name);
212 g_string_append (output, " ");
214 output = g_string_append (output, "]\n");
215 g_message ("%s", output->str);
216 g_string_free (output, TRUE);
217 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
219 g_message ("END BUFFER");
223 static const GtkActionEntry hildon2_msg_edit_action_entries [] = {
224 { "MessageSettings", NULL, N_("mcen_me_message_settings"), NULL, NULL, G_CALLBACK (on_message_settings)},
228 /* static gboolean */
229 /* on_key_pressed (GtkWidget *self, */
230 /* GdkEventKey *event, */
231 /* gpointer user_data); */
233 /* list my signals */
240 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
241 struct _ModestMsgEditWindowPrivate {
243 GtkWidget *header_box;
245 ModestPairList *from_field_protos;
246 GtkWidget *from_field;
247 gchar *last_from_account;
248 gchar *original_account_name;
253 gchar *original_mailbox;
257 GtkWidget *bcc_field;
258 GtkWidget *subject_field;
259 GtkWidget *attachments_view;
260 GtkWidget *priority_icon;
261 GtkWidget *subject_box;
262 GtkWidget *add_attachment_button;
264 GtkWidget *cc_caption;
265 GtkWidget *bcc_caption;
266 gboolean update_caption_visibility;
267 GtkWidget *attachments_caption;
269 GtkTextBuffer *text_buffer;
271 GtkWidget *font_size_toolitem;
272 GtkWidget *font_face_toolitem;
273 GtkWidget *font_color_button;
274 GtkWidget *font_color_toolitem;
275 GSList *font_items_group;
276 GtkTreeModel *faces_model;
277 gint current_face_index;
278 GtkWidget *font_tool_button_label;
279 GtkTreeModel *sizes_model;
280 gint current_size_index;
281 GtkWidget *size_tool_button_label;
283 GtkWidget *find_toolbar;
286 GtkWidget *font_dialog;
289 guint correct_scroll_idle;
290 guint scroll_drag_timeout_id;
294 TnyList *attachments;
299 TnyHeaderFlags priority_flags;
301 gboolean can_undo, can_redo;
302 gulong clipboard_change_handler_id;
303 gulong default_clipboard_change_handler_id;
304 gulong account_removed_handler_id;
305 guint clipboard_owner_idle;
306 gchar *clipboard_text;
315 GtkWidget *cc_button;
316 GtkWidget *bcc_button;
319 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
320 MODEST_TYPE_MSG_EDIT_WINDOW, \
321 ModestMsgEditWindowPrivate))
323 static GtkWindowClass *parent_class = NULL;
325 /* uncomment the following if you have defined any signals */
326 /* static guint signals[LAST_SIGNAL] = {0}; */
329 modest_msg_edit_window_get_type (void)
331 static GType my_type = 0;
333 static const GTypeInfo my_info = {
334 sizeof(ModestMsgEditWindowClass),
335 NULL, /* base init */
336 NULL, /* base finalize */
337 (GClassInitFunc) modest_msg_edit_window_class_init,
338 NULL, /* class finalize */
339 NULL, /* class data */
340 sizeof(ModestMsgEditWindow),
342 (GInstanceInitFunc) modest_msg_edit_window_init,
345 my_type = g_type_register_static (MODEST_TYPE_HILDON2_WINDOW,
346 "ModestMsgEditWindow",
354 save_state (ModestWindow *self)
356 modest_widget_memory_save (modest_runtime_get_conf(),
357 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
362 restore_settings (ModestMsgEditWindow *self)
364 ModestConf *conf = NULL;
366 conf = modest_runtime_get_conf ();
368 /* Dim at start clipboard actions */
369 modest_widget_memory_restore (conf, G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
374 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
376 GObjectClass *gobject_class;
377 ModestWindowClass *modest_window_class;
378 gobject_class = (GObjectClass*) klass;
379 modest_window_class = (ModestWindowClass*) klass;
381 parent_class = g_type_class_peek_parent (klass);
382 gobject_class->finalize = modest_msg_edit_window_finalize;
384 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
385 modest_window_class->save_state_func = save_state;
386 modest_window_class->disconnect_signals_func = modest_msg_edit_window_disconnect_signals;
388 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
392 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
394 ModestMsgEditWindowPrivate *priv;
395 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
397 priv->msg_body = NULL;
398 priv->from_field = NULL;
399 priv->to_field = NULL;
400 priv->cc_field = NULL;
401 priv->bcc_field = NULL;
402 priv->subject_field = NULL;
403 priv->attachments = TNY_LIST (tny_simple_list_new ());
404 priv->images = TNY_LIST (tny_simple_list_new ());
405 priv->images_size = 0;
406 priv->images_count = 0;
409 priv->cc_caption = NULL;
410 priv->bcc_caption = NULL;
411 priv->update_caption_visibility = FALSE;
413 priv->priority_flags = 0;
415 priv->find_toolbar = NULL;
416 priv->last_search = NULL;
418 priv->draft_msg = NULL;
419 priv->outbox_msg = NULL;
420 priv->msg_uid = NULL;
422 priv->can_undo = FALSE;
423 priv->can_redo = FALSE;
424 priv->clipboard_change_handler_id = 0;
425 priv->default_clipboard_change_handler_id = 0;
426 priv->account_removed_handler_id = 0;
427 priv->clipboard_owner_idle = 0;
428 priv->clipboard_text = NULL;
431 priv->scroll_drag_timeout_id = 0;
432 priv->correct_scroll_idle = 0;
433 priv->last_upper = 0.0;
435 priv->font_dialog = NULL;
436 priv->app_menu = NULL;
438 priv->references = NULL;
439 priv->in_reply_to = NULL;
441 if (!is_wp_text_buffer_started) {
442 is_wp_text_buffer_started = TRUE;
443 wp_text_buffer_library_init ();
448 hildon_program_add_window (hildon_program_get_instance(),
453 multimailbox_get_default_mailbox (const gchar *account_name)
455 gchar *transport_account;
456 gchar *result = NULL;
458 transport_account = modest_account_mgr_get_server_account_name (modest_runtime_get_account_mgr (),
460 TNY_ACCOUNT_TYPE_TRANSPORT);
461 if (transport_account) {
463 ModestProtocolRegistry *registry;
465 registry = modest_runtime_get_protocol_registry ();
467 proto = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), transport_account,
468 MODEST_ACCOUNT_PROTO, TRUE);
470 ModestProtocol *protocol =
471 modest_protocol_registry_get_protocol_by_name (registry,
472 MODEST_PROTOCOL_REGISTRY_TRANSPORT_PROTOCOLS,
474 if (MODEST_ACCOUNT_PROTOCOL (protocol)) {
475 ModestPairList *pair_list;
477 pair_list = modest_account_protocol_get_from_list (MODEST_ACCOUNT_PROTOCOL (protocol),
480 ModestPair *pair = (ModestPair *) pair_list->data;
481 result = g_strdup ((const gchar *) pair->first);
482 modest_pair_list_free (pair_list);
493 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
495 static ModestPairList*
496 get_transports (void)
498 GSList *transports = NULL;
500 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
501 GSList *accounts = modest_account_mgr_account_names (account_mgr,
502 TRUE /* only enabled accounts. */);
504 GSList *cursor = accounts;
506 gchar *account_name = cursor->data;
509 gchar *transport_account;
510 gboolean multi_mailbox = FALSE;
511 ModestProtocol *protocol = NULL;
513 if (modest_account_mgr_account_is_multimailbox (account_mgr, account_name, &protocol)) {
515 transport_account = modest_account_mgr_get_server_account_name
516 (modest_runtime_get_account_mgr (),
518 TNY_ACCOUNT_TYPE_TRANSPORT);
519 if (protocol && MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
520 ModestPairList *pair_list;
521 pair_list = modest_account_protocol_get_from_list (MODEST_ACCOUNT_PROTOCOL (protocol),
524 transports = g_slist_concat (transports, pair_list);
525 multi_mailbox = TRUE;
530 if (!multi_mailbox) {
531 gchar *from_string = NULL;
533 from_string = modest_account_mgr_get_from_string (account_mgr,
535 if (from_string && account_name) {
536 gchar *name = account_name;
537 ModestPair *pair = modest_pair_new ((gpointer) name,
538 (gpointer) from_string , TRUE);
539 transports = g_slist_prepend (transports, pair);
544 cursor = cursor->next;
546 g_slist_free (accounts); /* only free the accounts, not the elements,
547 * because they are used in the pairlist */
551 static void window_focus (GtkWindow *window,
555 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
559 scroll_drag_timeout (gpointer userdata)
561 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
562 ModestMsgEditWindowPrivate *priv;
564 /* It could happen that the window was already closed */
565 if (!GTK_WIDGET_VISIBLE (win))
568 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
570 correct_scroll_without_drag_check (win, TRUE);
572 priv->scroll_drag_timeout_id = 0;
578 correct_scroll_without_drag_check_idle (gpointer userdata)
580 ModestMsgEditWindow *w = (ModestMsgEditWindow *) userdata;
581 ModestMsgEditWindowPrivate *priv;
583 GdkRectangle rectangle;
584 gint offset_min, offset_max;
588 /* It could happen that the window was already closed */
589 if (!GTK_WIDGET_VISIBLE (w))
592 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
594 insert = gtk_text_buffer_get_insert (priv->text_buffer);
595 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
597 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
598 offset_min = priv->msg_body->allocation.y + rectangle.y;
599 offset_max = offset_min + rectangle.height;
601 vadj = hildon_pannable_area_get_vadjustment (HILDON_PANNABLE_AREA (priv->pannable));
602 offset_min = MAX (offset_min - 48, 0);
603 offset_max = MIN (offset_max + 48, vadj->upper);
605 gtk_adjustment_clamp_page (vadj, (gdouble) offset_min, (gdouble) offset_max);
607 priv->correct_scroll_idle = 0;
612 correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused)
614 ModestMsgEditWindowPrivate *priv;
616 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
618 if (only_if_focused && !gtk_widget_is_focus (priv->msg_body))
621 if (priv->correct_scroll_idle > 0) {
625 priv->correct_scroll_idle = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
626 (GSourceFunc) correct_scroll_without_drag_check_idle,
632 correct_scroll (ModestMsgEditWindow *w)
634 ModestMsgEditWindowPrivate *priv;
636 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
637 if (gtk_grab_get_current () == priv->msg_body) {
638 if (priv->scroll_drag_timeout_id == 0) {
639 priv->scroll_drag_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
641 (GSourceFunc) scroll_drag_timeout,
648 correct_scroll_without_drag_check (w, TRUE);
652 text_buffer_end_user_action (GtkTextBuffer *buffer,
653 ModestMsgEditWindow *userdata)
656 correct_scroll (userdata);
660 text_buffer_mark_set (GtkTextBuffer *buffer,
663 ModestMsgEditWindow *userdata)
665 gtk_text_buffer_begin_user_action (buffer);
666 gtk_text_buffer_end_user_action (buffer);
670 cut_clipboard_check (GtkTextView *text_view,
673 GtkTextBuffer *buffer;
675 buffer = gtk_text_view_get_buffer (text_view);
676 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
677 g_signal_stop_emission_by_name ((gpointer )text_view, "cut-clipboard");
682 copy_clipboard_check (GtkTextView *text_view,
685 GtkTextBuffer *buffer;
687 buffer = gtk_text_view_get_buffer (text_view);
688 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
689 g_signal_stop_emission_by_name ((gpointer )text_view, "copy-clipboard");
694 attachment_deleted (ModestAttachmentsView *attachments_view,
697 modest_msg_edit_window_remove_attachments (MODEST_MSG_EDIT_WINDOW (user_data),
702 connect_signals (ModestMsgEditWindow *obj)
704 ModestMsgEditWindowPrivate *priv;
706 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
708 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
709 G_CALLBACK (text_buffer_refresh_attributes), obj);
710 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
711 G_CALLBACK (text_buffer_can_undo), obj);
712 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
713 G_CALLBACK (text_buffer_can_redo), obj);
714 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
715 G_CALLBACK (body_changed), obj);
716 g_signal_connect (G_OBJECT (priv->text_buffer), "modified-changed",
717 G_CALLBACK (body_changed), obj);
718 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
719 G_CALLBACK (text_buffer_end_user_action), obj);
720 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
721 G_CALLBACK (text_buffer_mark_set), obj);
722 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
723 G_CALLBACK (text_buffer_apply_tag), obj);
724 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
725 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
726 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
727 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
728 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
729 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
731 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
732 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
733 g_signal_connect (G_OBJECT (priv->from_field), "value-changed",
734 G_CALLBACK (from_field_changed), obj);
736 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
737 G_CALLBACK (msg_body_focus), obj);
738 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
739 G_CALLBACK (msg_body_focus), obj);
740 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
741 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
742 "changed", G_CALLBACK (recpt_field_changed), obj);
743 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
744 "changed", G_CALLBACK (recpt_field_changed), obj);
745 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
746 "changed", G_CALLBACK (recpt_field_changed), obj);
747 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
748 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
749 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
751 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
752 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
754 priv->clipboard_change_handler_id =
755 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
756 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
757 priv->default_clipboard_change_handler_id =
758 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
759 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
761 g_signal_connect (G_OBJECT (priv->msg_body), "cut-clipboard", G_CALLBACK (cut_clipboard_check), NULL);
762 g_signal_connect (G_OBJECT (priv->msg_body), "copy-clipboard", G_CALLBACK (copy_clipboard_check), NULL);
763 g_signal_connect (G_OBJECT (priv->attachments_view), "delete", G_CALLBACK (attachment_deleted), obj);
767 init_wp_text_view_style ()
769 static gboolean initialized = FALSE;
772 gtk_rc_parse_string ("class \"WPTextView\" style \"fremantle-textview\"");
778 init_window (ModestMsgEditWindow *obj)
780 GtkWidget *to_caption, *subject_caption;
781 GtkWidget *main_vbox;
782 GtkWidget *add_attachment_align;
783 ModestMsgEditWindowPrivate *priv;
784 GtkActionGroup *action_group;
785 ModestWindowPrivate *parent_priv;
786 GdkPixbuf *window_icon = NULL;
787 GError *error = NULL;
789 GtkSizeGroup *title_size_group;
790 GtkSizeGroup *value_size_group;
791 GtkWidget *attachment_icon;
792 GtkWidget *window_box;
793 GtkWidget *window_align;
794 #if (GTK_MINOR_VERSION >= 10)
795 GdkAtom deserialize_type;
798 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
799 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
801 parent_priv->ui_manager = gtk_ui_manager_new();
802 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
803 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
805 /* Add common actions */
806 gtk_action_group_add_actions (action_group,
807 modest_msg_edit_action_entries,
808 G_N_ELEMENTS (modest_msg_edit_action_entries),
810 gtk_action_group_add_actions (action_group,
811 hildon2_msg_edit_action_entries,
812 G_N_ELEMENTS (hildon2_msg_edit_action_entries),
814 gtk_action_group_add_toggle_actions (action_group,
815 modest_msg_edit_toggle_action_entries,
816 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
818 gtk_action_group_add_radio_actions (action_group,
819 modest_msg_edit_alignment_radio_action_entries,
820 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
822 G_CALLBACK (modest_ui_actions_on_change_justify),
824 gtk_action_group_add_radio_actions (action_group,
825 modest_msg_edit_priority_action_entries,
826 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
828 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
830 gtk_action_group_add_radio_actions (action_group,
831 modest_msg_edit_file_format_action_entries,
832 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
833 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
834 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
836 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
837 g_object_unref (action_group);
839 /* Load the UI definition */
840 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
843 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
844 g_clear_error (&error);
847 /* Add accelerators */
848 gtk_window_add_accel_group (GTK_WINDOW (obj),
849 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
851 parent_priv->menubar = NULL;
853 title_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
854 value_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
856 /* Note: This ModestPairList* must exist for as long as the picker
857 * that uses it, because the ModestSelectorPicker uses the ID opaquely,
858 * so it can't know how to manage its memory. */
859 priv->from_field = modest_selector_picker_new (MODEST_EDITABLE_SIZE,
860 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
862 modest_selector_picker_set_value_max_chars (MODEST_SELECTOR_PICKER (priv->from_field), MAX_FROM_VALUE);
863 modest_maemo_utils_set_hbutton_layout (title_size_group, value_size_group,
864 _("mail_va_from"), priv->from_field);
866 priv->to_field = modest_recpt_editor_new ();
867 priv->cc_field = modest_recpt_editor_new ();
868 priv->bcc_field = modest_recpt_editor_new ();
869 priv->subject_box = gtk_hbox_new (FALSE, MODEST_MARGIN_NONE);
870 priv->priority_icon = gtk_image_new ();
871 gtk_box_pack_start (GTK_BOX (priv->subject_box), priv->priority_icon, FALSE, FALSE, 0);
872 priv->subject_field = hildon_entry_new (MODEST_EDITABLE_SIZE);
873 gtk_entry_set_max_length (GTK_ENTRY (priv->subject_field) ,SUBJECT_MAX_LENGTH);
874 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
875 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
876 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
877 gtk_box_pack_start (GTK_BOX (priv->subject_box), priv->subject_field, TRUE, TRUE, 0);
878 priv->add_attachment_button = hildon_button_new (MODEST_EDITABLE_SIZE, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
879 gtk_widget_set_size_request (priv->add_attachment_button, ATTACHMENT_BUTTON_WIDTH, -1);
880 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
881 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
882 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, HILDON_ICON_SIZE_FINGER);
883 hildon_button_set_image (HILDON_BUTTON (priv->add_attachment_button), attachment_icon);
884 add_attachment_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
885 gtk_alignment_set_padding (GTK_ALIGNMENT (add_attachment_align), 0, 0, MODEST_MARGIN_DEFAULT, 0);
886 gtk_container_add (GTK_CONTAINER (add_attachment_align), priv->add_attachment_button);
887 gtk_box_pack_start (GTK_BOX (priv->subject_box), add_attachment_align, FALSE, FALSE, 0);
888 priv->attachments_view = modest_attachments_view_new (NULL);
889 modest_attachments_view_set_style (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
890 MODEST_ATTACHMENTS_VIEW_STYLE_NO_FOCUS);
892 priv->header_box = gtk_vbox_new (FALSE, 0);
894 to_caption = modest_maemo_utils_create_captioned_with_size_type
895 (title_size_group, value_size_group,
896 _("mail_va_to"), FALSE, priv->to_field,
897 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
898 priv->cc_caption = modest_maemo_utils_create_captioned_with_size_type
899 (title_size_group, value_size_group,
900 _("mail_va_cc"), FALSE, priv->cc_field,
901 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
902 priv->bcc_caption = modest_maemo_utils_create_captioned_with_size_type
903 (title_size_group, value_size_group,
904 _("mail_va_hotfix1"), FALSE, priv->bcc_field,
905 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
906 subject_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
907 _("mail_va_subject"), FALSE, priv->subject_box);
908 priv->attachments_caption = modest_maemo_utils_create_captioned_with_size_type (title_size_group, value_size_group,
909 _("mail_va_attachment"),
911 priv->attachments_view,
912 HILDON_SIZE_AUTO_WIDTH |
913 HILDON_SIZE_AUTO_HEIGHT);
914 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), value_size_group); */
915 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), value_size_group); */
916 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), value_size_group); */
917 g_object_unref (title_size_group);
918 g_object_unref (value_size_group);
920 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->from_field, FALSE, FALSE, 0);
921 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
922 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
923 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
924 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
925 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
926 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
928 init_wp_text_view_style ();
930 priv->msg_body = modest_wp_text_view_new ();
933 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
934 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
935 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
936 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
937 #if (GTK_MINOR_VERSION >= 10)
938 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), NULL);
939 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
941 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
942 deserialize_type, TRUE);
944 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
946 priv->find_toolbar = hildon_find_toolbar_new (NULL);
947 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
949 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
951 priv->pannable = hildon_pannable_area_new ();
953 g_object_set (G_OBJECT (priv->pannable), "hscrollbar-policy", GTK_POLICY_NEVER, NULL);
955 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
956 window_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
957 gtk_alignment_set_padding (GTK_ALIGNMENT (window_align), 0, 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DEFAULT);
959 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
960 gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 0);
961 gtk_container_add (GTK_CONTAINER (window_align), main_vbox);
963 hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA (priv->pannable), window_align);
964 gtk_widget_show_all (GTK_WIDGET(priv->pannable));
966 window_box = gtk_vbox_new (FALSE, 0);
967 gtk_container_add (GTK_CONTAINER(obj), window_box);
969 gtk_box_pack_start (GTK_BOX (window_box), priv->pannable, TRUE, TRUE, 0);
971 /* Set window icon */
972 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
974 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
975 g_object_unref (window_icon);
980 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
982 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
984 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
985 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
986 priv->clipboard_change_handler_id))
987 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
988 priv->clipboard_change_handler_id);
989 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
990 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
991 priv->default_clipboard_change_handler_id))
992 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
993 priv->default_clipboard_change_handler_id);
995 if (priv->account_removed_handler_id &&
996 g_signal_handler_is_connected (modest_runtime_get_account_store (),
997 priv->account_removed_handler_id))
998 g_signal_handler_disconnect(modest_runtime_get_account_store (),
999 priv->account_removed_handler_id);
1003 modest_msg_edit_window_finalize (GObject *obj)
1005 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1007 /* Sanity check: shouldn't be needed, the window mgr should
1008 call this function before */
1009 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
1011 if (priv->font_dialog != NULL) {
1012 gtk_dialog_response (GTK_DIALOG (priv->font_dialog), GTK_RESPONSE_NONE);
1015 if (priv->clipboard_text != NULL) {
1016 g_free (priv->clipboard_text);
1017 priv->clipboard_text = NULL;
1020 if (priv->draft_msg != NULL) {
1021 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
1022 if (TNY_IS_HEADER (header)) {
1023 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1024 modest_window_mgr_unregister_header (mgr, header);
1026 g_object_unref (priv->draft_msg);
1027 priv->draft_msg = NULL;
1029 if (priv->outbox_msg != NULL) {
1030 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
1031 if (TNY_IS_HEADER (header)) {
1032 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1033 modest_window_mgr_unregister_header (mgr, header);
1035 g_object_unref (priv->outbox_msg);
1036 priv->outbox_msg = NULL;
1038 if (priv->correct_scroll_idle > 0) {
1039 g_source_remove (priv->correct_scroll_idle);
1040 priv->correct_scroll_idle = 0;
1042 if (priv->scroll_drag_timeout_id > 0) {
1043 g_source_remove (priv->scroll_drag_timeout_id);
1044 priv->scroll_drag_timeout_id = 0;
1046 if (priv->clipboard_owner_idle > 0) {
1047 g_source_remove (priv->clipboard_owner_idle);
1048 priv->clipboard_owner_idle = 0;
1050 if (priv->original_account_name)
1051 g_free (priv->original_account_name);
1052 if (priv->original_mailbox)
1053 g_free (priv->original_mailbox);
1054 g_free (priv->msg_uid);
1055 g_free (priv->last_search);
1056 g_free (priv->references);
1057 g_free (priv->in_reply_to);
1058 g_object_unref (priv->faces_model);
1059 g_object_unref (priv->sizes_model);
1060 g_object_unref (priv->attachments);
1061 g_object_unref (priv->images);
1063 /* This had to stay alive for as long as the picker that used it: */
1064 modest_pair_list_free (priv->from_field_protos);
1066 G_OBJECT_CLASS(parent_class)->finalize (obj);
1070 pixbuf_size_prepared (GdkPixbufLoader *loader,
1073 ModestMsgEditWindow *self)
1075 gint new_height, new_width;
1078 new_height = height;
1082 if (width > IMAGE_MAX_WIDTH) {
1083 new_height = height * IMAGE_MAX_WIDTH / width;
1084 new_width = IMAGE_MAX_WIDTH;
1087 gdk_pixbuf_loader_set_size (loader, new_width, new_height);
1091 pixbuf_from_stream (TnyStream *stream,
1092 const gchar *mime_type,
1093 guint64 *stream_size,
1094 ModestMsgEditWindow *self)
1096 GdkPixbufLoader *loader;
1099 GError *error = NULL;
1103 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1105 if (loader == NULL) {
1110 g_signal_connect (G_OBJECT (loader), "size-prepared", G_CALLBACK (pixbuf_size_prepared), self);
1112 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), TRUE);
1114 tny_stream_reset (TNY_STREAM (stream));
1115 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1116 unsigned char read_buffer[128];
1118 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1120 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, &error)) {
1123 /* Allow some UI responsiveness */
1124 while (gtk_events_pending ())
1125 gtk_main_iteration ();
1127 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), FALSE);
1129 gdk_pixbuf_loader_close (loader, &error);
1132 g_error_free (error);
1133 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1135 g_object_ref (pixbuf);
1136 g_object_unref (loader);
1141 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1142 GdkPixbuf *new_pixbuf;
1144 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1145 gdk_pixbuf_get_width (pixbuf);
1146 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1147 g_object_unref (pixbuf);
1148 pixbuf = new_pixbuf;
1152 *stream_size = size;
1158 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1160 ModestMsgEditWindowPrivate *priv;
1163 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1165 g_object_ref (self);
1166 for (iter = tny_list_create_iterator (attachments);
1167 !tny_iterator_is_done (iter);
1168 tny_iterator_next (iter)) {
1169 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1170 const gchar *cid = tny_mime_part_get_content_id (part);
1171 const gchar *mime_type = tny_mime_part_get_content_type (part);
1172 if ((cid != NULL)&&(mime_type != NULL)) {
1173 guint64 stream_size;
1174 TnyStream *stream = tny_mime_part_get_decoded_stream (part);
1175 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size, self);
1178 g_object_unref (stream);
1180 if (pixbuf != NULL) {
1181 priv->images_count ++;
1182 priv->images_size += stream_size;
1183 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1184 g_object_unref (pixbuf);
1187 g_object_unref (part);
1189 g_object_unref (iter);
1190 g_object_unref (self);
1194 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1196 TnyMimePart *parent = NULL;
1197 const gchar *content_type = NULL;
1198 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1200 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1202 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1203 parent = g_object_ref (msg);
1204 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1205 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1208 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1209 iter = tny_list_create_iterator (parts);
1210 while (!tny_iterator_is_done (iter)) {
1212 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1213 content_type = tny_mime_part_get_content_type (part);
1214 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1218 g_object_unref (part);
1220 tny_iterator_next (iter);
1222 g_object_unref (iter);
1223 g_object_unref (parts);
1226 if (parent != NULL) {
1227 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1230 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1231 iter = tny_list_create_iterator (parts);
1232 while (!tny_iterator_is_done (iter)) {
1234 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1235 content_type = tny_mime_part_get_content_type (part);
1236 if (content_type && g_str_has_prefix (content_type, "image/")) {
1237 tny_list_prepend (priv->images, (GObject *) part);
1239 g_object_unref (part);
1240 tny_iterator_next (iter);
1242 g_object_unref (iter);
1243 g_object_unref (parts);
1244 g_object_unref (parent);
1249 update_next_cid (ModestMsgEditWindow *self, TnyList *attachments)
1252 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1254 for (iter = tny_list_create_iterator (attachments) ;
1255 !tny_iterator_is_done (iter);
1256 tny_iterator_next (iter)) {
1257 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1258 const gchar *cid = tny_mime_part_get_content_id (part);
1260 char *invalid = NULL;
1261 gint int_cid = strtol (cid, &invalid, 10);
1262 if ((invalid != NULL) && (*invalid == '\0') && (int_cid >= priv->next_cid)) {
1263 priv->next_cid = int_cid + 1;
1266 g_object_unref (part);
1268 g_object_unref (iter);
1272 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1275 gchar *to, *cc, *bcc, *subject;
1277 ModestMsgEditWindowPrivate *priv;
1278 ModestWindowPrivate *parent_priv;
1280 TnyHeaderFlags priority_flags;
1281 TnyFolder *msg_folder;
1282 gboolean is_html = FALSE;
1283 gboolean field_view_set;
1285 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1286 g_return_if_fail (TNY_IS_MSG (msg));
1288 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1289 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1291 header = tny_msg_get_header (msg);
1292 to = tny_header_dup_to (header);
1293 cc = tny_header_dup_cc (header);
1294 bcc = tny_header_dup_bcc (header);
1295 subject = tny_header_dup_subject (header);
1297 modest_tny_msg_get_references (TNY_MSG (msg), NULL, &(priv->references), &(priv->in_reply_to));
1298 priority_flags = tny_header_get_priority (header);
1301 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1303 field_view_set = TRUE;
1305 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1306 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1307 gtk_widget_show (priv->cc_caption);
1308 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1309 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1310 gtk_widget_hide (priv->cc_caption);
1311 field_view_set = FALSE;
1313 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->cc_button), field_view_set);
1315 field_view_set = TRUE;
1317 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1318 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1319 gtk_widget_show (priv->bcc_caption);
1320 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1321 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1322 gtk_widget_hide (priv->bcc_caption);
1323 field_view_set = FALSE;
1325 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->bcc_button), field_view_set);
1329 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1330 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1333 update_window_title (self);
1335 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1336 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1338 if ((body == NULL)||(body[0] == '\0')) {
1340 body = modest_text_utils_convert_to_html ("");
1343 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1344 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1347 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1350 /* Add attachments to the view */
1351 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1352 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1353 if (tny_list_get_length (priv->attachments) == 0) {
1354 gtk_widget_hide (priv->attachments_caption);
1356 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1357 gtk_widget_show_all (priv->attachments_caption);
1359 get_related_images (self, msg);
1360 update_next_cid (self, priv->attachments);
1361 update_next_cid (self, priv->images);
1362 replace_with_images (self, priv->images);
1364 if (preserve_is_rich && !is_html) {
1365 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1366 /* Get the default format required from configuration */
1367 } else if (!preserve_is_rich && !modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1368 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1371 /* Set the default focus depending on having already a To: field or not */
1372 if ((!to)||(*to == '\0')) {
1373 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1375 gtk_widget_grab_focus (priv->msg_body);
1378 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1380 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1381 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1383 modest_msg_edit_window_set_modified (self, FALSE);
1385 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1386 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1387 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1388 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1390 if (priv->msg_uid) {
1391 g_free (priv->msg_uid);
1392 priv->msg_uid = NULL;
1395 /* we should set a reference to the incoming message if it is a draft */
1396 msg_folder = tny_msg_get_folder (msg);
1398 if (modest_tny_folder_is_local_folder (msg_folder)) {
1399 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1400 if (type == TNY_FOLDER_TYPE_INVALID)
1401 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1403 if (type == TNY_FOLDER_TYPE_DRAFTS)
1404 priv->draft_msg = g_object_ref(msg);
1405 if (type == TNY_FOLDER_TYPE_OUTBOX)
1406 priv->outbox_msg = g_object_ref(msg);
1407 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1409 g_object_unref (msg_folder);
1420 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1422 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1423 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1424 GtkWidget *placeholder;
1425 GtkWidget *tool_item;
1430 GtkWidget *sizes_menu;
1431 GtkWidget *fonts_menu;
1437 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1438 gtk_toolbar_set_show_arrow (GTK_TOOLBAR (parent_priv->toolbar), FALSE);
1439 gtk_toolbar_set_icon_size (GTK_TOOLBAR (parent_priv->toolbar), HILDON_ICON_SIZE_FINGER);
1440 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1442 /* Font color placeholder */
1443 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1444 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1447 priv->font_color_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1448 priv->font_color_button = hildon_color_button_new ();
1449 gtk_widget_set_size_request (priv->font_color_button, -1, 48);
1450 GTK_WIDGET_UNSET_FLAGS (priv->font_color_toolitem, GTK_CAN_FOCUS);
1451 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1452 gtk_container_add (GTK_CONTAINER (priv->font_color_toolitem), priv->font_color_button);
1453 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1454 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1455 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->font_color_toolitem), insert_index);
1456 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1458 G_CALLBACK (modest_msg_edit_window_color_button_change),
1461 /* Font size and face placeholder */
1462 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1463 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1465 tool_item = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
1466 priv->size_tool_button_label = gtk_label_new (NULL);
1467 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1468 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1469 size_text, "</span>", NULL);
1470 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1471 gtk_misc_set_alignment (GTK_MISC (priv->size_tool_button_label), 1.0, 0.5);
1473 hildon_helper_set_logical_font (priv->size_tool_button_label, "LargeSystemFont");
1474 hbox = gtk_hbox_new (MODEST_MARGIN_DEFAULT, FALSE);
1475 gtk_box_pack_start (GTK_BOX (hbox), priv->size_tool_button_label, TRUE, TRUE, 0);
1476 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1477 gtk_misc_set_alignment (GTK_MISC (arrow), 0.0, 0.5);
1478 gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
1479 gtk_widget_set_sensitive (arrow, FALSE);
1480 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), hbox);
1481 sizes_menu = gtk_menu_new ();
1482 priv->sizes_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
1483 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1486 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1487 gtk_list_store_append (GTK_LIST_STORE (priv->sizes_model), &iter);
1489 gtk_list_store_set (GTK_LIST_STORE (priv->sizes_model), &iter,
1493 if (wp_font_size[size_index] == 12)
1494 priv->current_size_index = size_index;
1498 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (font_size_clicked), window);
1499 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1500 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1501 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1502 priv->font_size_toolitem = tool_item;
1505 tool_item = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
1506 priv->font_tool_button_label = gtk_label_new (NULL);
1507 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1508 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1509 gtk_misc_set_alignment (GTK_MISC (priv->font_tool_button_label), 1.0, 0.5);
1511 hildon_helper_set_logical_font (priv->font_tool_button_label, "LargeSystemFont");
1512 hbox = gtk_hbox_new (MODEST_MARGIN_DEFAULT, FALSE);
1513 gtk_box_pack_start (GTK_BOX (hbox), priv->font_tool_button_label, TRUE, TRUE, 0);
1514 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1515 gtk_misc_set_alignment (GTK_MISC (arrow), 0.0, 0.5);
1516 gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
1517 gtk_widget_set_sensitive (arrow, FALSE);
1518 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), hbox);
1519 fonts_menu = gtk_menu_new ();
1520 priv->faces_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
1521 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1524 gtk_list_store_append (GTK_LIST_STORE (priv->faces_model), &iter);
1526 gtk_list_store_set (GTK_LIST_STORE (priv->faces_model), &iter,
1527 0, wp_get_font_name (font_index),
1530 if (font_index == DEFAULT_FONT)
1531 priv->current_face_index = font_index;
1533 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (font_face_clicked), window);
1534 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1535 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1536 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1537 priv->font_face_toolitem = tool_item;
1539 /* Set expand and homogeneous for remaining items */
1540 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1541 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1542 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1543 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1544 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1545 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1546 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1547 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1548 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1550 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1551 will not show the tool items added to the placeholders) */
1552 gtk_widget_show_all (parent_priv->toolbar);
1554 /* Set the no show all *after* showing all items. We do not
1555 want the toolbar to be shown with a show all because it
1556 could go agains the gconf setting regarding showing or not
1557 the toolbar of the editor window */
1558 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1564 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, const gchar *mailbox, gboolean preserve_is_rich)
1567 ModestWindowPrivate *parent_priv;
1568 ModestMsgEditWindowPrivate *priv;
1569 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1570 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1571 ModestWindowMgr *mgr = NULL;
1573 g_return_val_if_fail (msg, NULL);
1574 g_return_val_if_fail (account_name, NULL);
1576 mgr = modest_runtime_get_window_mgr ();
1578 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1580 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1581 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1583 /* Menubar. Update the state of some toggles */
1584 priv->from_field_protos = get_transports ();
1585 priv->original_mailbox = NULL;
1586 modest_selector_picker_set_pair_list (MODEST_SELECTOR_PICKER (priv->from_field), priv->from_field_protos);
1587 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1588 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1589 if (mailbox && modest_pair_list_find_by_first_as_string (priv->from_field_protos, mailbox)) {
1590 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) mailbox);
1591 priv->original_mailbox = g_strdup (mailbox);
1592 } else if (modest_account_mgr_account_is_multimailbox (modest_runtime_get_account_mgr (), account_name, NULL)) {
1593 /* We set the first mailbox as the active mailbox */
1594 priv->original_mailbox = multimailbox_get_default_mailbox (account_name);
1595 if (priv->original_mailbox != NULL)
1596 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field),
1597 (gpointer) priv->original_mailbox);
1599 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field),
1600 (gpointer) account_name);
1602 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1604 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1605 hildon_button_set_title (HILDON_BUTTON (priv->from_field),
1607 hildon_button_set_value (HILDON_BUTTON (priv->from_field),
1608 hildon_touch_selector_get_current_text
1609 (HILDON_TOUCH_SELECTOR (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (priv->from_field)))));
1610 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1611 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1614 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1616 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1618 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1619 modest_window_set_active_mailbox (MODEST_WINDOW(obj), priv->original_mailbox);
1621 priv->original_account_name = (account_name) ? g_strdup (account_name) : NULL;
1623 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1624 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1625 /* Add common dimming rules */
1626 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1627 modest_msg_edit_window_toolbar_dimming_entries,
1628 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1629 MODEST_WINDOW (obj));
1630 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_toolitem,
1631 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1632 MODEST_WINDOW (obj));
1633 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1634 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1635 MODEST_WINDOW (obj));
1636 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1637 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1638 MODEST_WINDOW (obj));
1639 /* Insert dimming rules group for this window */
1640 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1641 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1643 /* Setup app menu */
1644 setup_menu (MODEST_MSG_EDIT_WINDOW (obj));
1646 /* Checks the dimming rules */
1647 g_object_unref (toolbar_rules_group);
1648 g_object_unref (clipboard_rules_group);
1649 gtk_widget_hide (priv->priority_icon);
1650 gtk_widget_queue_resize (priv->subject_box);
1651 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1653 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1655 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1656 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1657 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1658 priv->update_caption_visibility = TRUE;
1660 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1662 /* Track account-removed signal, this window should be closed
1663 in the case we're creating a mail associated to the account
1665 priv->account_removed_handler_id =
1666 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1668 G_CALLBACK(on_account_removed),
1671 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (MODEST_MSG_EDIT_WINDOW (obj));
1673 return (ModestWindow*) obj;
1677 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1679 GString **string_buffer = (GString **) user_data;
1681 *string_buffer = g_string_append (*string_buffer, buffer);
1687 * @result: A new string which should be freed with g_free().
1690 get_formatted_data (ModestMsgEditWindow *edit_window)
1692 ModestMsgEditWindowPrivate *priv;
1693 GString *string_buffer = g_string_new ("");
1695 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1697 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1699 modest_text_utils_hyperlinkify (string_buffer);
1701 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1703 return g_string_free (string_buffer, FALSE);
1708 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1711 const gchar *account_name;
1712 ModestMsgEditWindowPrivate *priv;
1713 TnyIterator *att_iter;
1714 const gchar *picker_active_id;
1716 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1718 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1720 picker_active_id = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1721 g_return_val_if_fail (picker_active_id, NULL);
1722 account_name = modest_utils_get_account_name_from_recipient (picker_active_id, NULL);
1724 /* don't free these (except from) */
1725 data = g_slice_new0 (MsgData);
1726 data->from = g_strdup ((gchar *) modest_selector_picker_get_active_display_name (MODEST_SELECTOR_PICKER (priv->from_field)));
1727 data->account_name = g_strdup (account_name);
1728 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1729 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1730 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1731 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1732 data->references = g_strdup (priv->references);
1733 data->in_reply_to = g_strdup (priv->in_reply_to);
1734 if (priv->draft_msg) {
1735 data->draft_msg = g_object_ref (priv->draft_msg);
1736 } else if (priv->outbox_msg) {
1737 data->draft_msg = g_object_ref (priv->outbox_msg);
1739 data->draft_msg = NULL;
1742 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1744 gtk_text_buffer_get_bounds (buf, &b, &e);
1745 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1747 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1748 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1750 data->html_body = NULL;
1752 /* deep-copy the data */
1753 att_iter = tny_list_create_iterator (priv->attachments);
1754 data->attachments = NULL;
1755 while (!tny_iterator_is_done (att_iter)) {
1756 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1757 if (!(TNY_IS_MIME_PART(part))) {
1758 g_warning ("strange data in attachment list");
1759 g_object_unref (part);
1760 tny_iterator_next (att_iter);
1763 data->attachments = g_list_append (data->attachments,
1765 tny_iterator_next (att_iter);
1767 g_object_unref (att_iter);
1769 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1770 att_iter = tny_list_create_iterator (priv->images);
1771 data->images = NULL;
1772 while (!tny_iterator_is_done (att_iter)) {
1773 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1775 if (!(TNY_IS_MIME_PART(part))) {
1776 g_warning ("strange data in attachment list");
1777 g_object_unref (part);
1778 tny_iterator_next (att_iter);
1781 cid = tny_mime_part_get_content_id (part);
1783 gchar *image_tag_id;
1784 GtkTextTag *image_tag;
1786 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1787 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1788 g_free (image_tag_id);
1790 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1792 ((gtk_text_iter_has_tag (&iter, image_tag))||
1793 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1794 data->images = g_list_append (data->images,
1795 g_object_ref (part));
1797 g_object_unref (part);
1798 tny_iterator_next (att_iter);
1800 g_object_unref (att_iter);
1802 data->priority_flags = priv->priority_flags;
1809 unref_gobject (GObject *obj, gpointer data)
1811 if (!G_IS_OBJECT(obj))
1813 g_object_unref (obj);
1817 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1820 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1828 g_free (data->from);
1829 g_free (data->subject);
1830 g_free (data->plain_body);
1831 g_free (data->html_body);
1832 g_free (data->account_name);
1833 g_free (data->references);
1834 g_free (data->in_reply_to);
1836 if (data->draft_msg != NULL) {
1837 g_object_unref (data->draft_msg);
1838 data->draft_msg = NULL;
1841 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1842 g_list_free (data->attachments);
1843 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1844 g_list_free (data->images);
1846 g_slice_free (MsgData, data);
1850 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1852 guint64 *parts_size)
1854 ModestMsgEditWindowPrivate *priv;
1856 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1858 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1860 /* TODO: add images */
1861 *parts_size += priv->images_size;
1862 *parts_count += priv->images_count;
1867 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1870 ModestMsgEditWindowPrivate *priv = NULL;
1871 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1873 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1875 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1877 return MODEST_MSG_EDIT_FORMAT_HTML;
1879 return MODEST_MSG_EDIT_FORMAT_TEXT;
1883 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1884 ModestMsgEditFormat format)
1886 ModestMsgEditWindowPrivate *priv;
1888 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1889 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1892 case MODEST_MSG_EDIT_FORMAT_HTML:
1893 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1895 case MODEST_MSG_EDIT_FORMAT_TEXT:
1896 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1899 g_return_if_reached ();
1903 ModestMsgEditFormatState *
1904 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1906 ModestMsgEditFormatState *format_state = NULL;
1907 ModestMsgEditWindowPrivate *priv;
1908 WPTextBufferFormat *buffer_format;
1910 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1912 buffer_format = g_new0 (WPTextBufferFormat, 1);
1913 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1915 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1917 format_state = g_new0 (ModestMsgEditFormatState, 1);
1918 format_state->bold = buffer_format->bold&0x1;
1919 format_state->italics = buffer_format->italic&0x1;
1920 format_state->bullet = buffer_format->bullet&0x1;
1921 format_state->color = buffer_format->color;
1922 format_state->font_size = buffer_format->font_size;
1923 format_state->font_family = wp_get_font_name (buffer_format->font);
1924 format_state->justification = buffer_format->justification;
1925 g_free (buffer_format);
1927 return format_state;
1932 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1933 const ModestMsgEditFormatState *format_state)
1935 ModestMsgEditWindowPrivate *priv;
1936 WPTextBufferFormat *buffer_format;
1937 WPTextBufferFormat *current_format;
1939 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1940 g_return_if_fail (format_state != NULL);
1942 buffer_format = g_new0 (WPTextBufferFormat, 1);
1943 current_format = g_new0 (WPTextBufferFormat, 1);
1945 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1946 gtk_widget_grab_focus (priv->msg_body);
1947 buffer_format->bold = (format_state->bold != FALSE);
1948 buffer_format->italic = (format_state->italics != FALSE);
1949 buffer_format->color = format_state->color;
1950 buffer_format->font_size = format_state->font_size;
1951 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1952 buffer_format->justification = format_state->justification;
1953 buffer_format->bullet = format_state->bullet;
1955 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1957 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1958 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1959 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1960 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1961 buffer_format->cs.font = (buffer_format->font != current_format->font);
1962 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1963 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1965 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1966 if (buffer_format->cs.bold) {
1967 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1968 GINT_TO_POINTER (buffer_format->bold&0x1));
1970 if (buffer_format->cs.italic) {
1971 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1972 GINT_TO_POINTER (buffer_format->italic&0x1));
1974 if (buffer_format->cs.color) {
1975 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1976 GINT_TO_POINTER (&(buffer_format->color)));
1978 if (buffer_format->cs.font_size) {
1979 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1980 GINT_TO_POINTER (buffer_format->font_size));
1982 if (buffer_format->cs.justification) {
1983 switch (buffer_format->justification) {
1984 case GTK_JUSTIFY_LEFT:
1985 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1986 GINT_TO_POINTER(TRUE));
1988 case GTK_JUSTIFY_CENTER:
1989 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
1990 GINT_TO_POINTER(TRUE));
1992 case GTK_JUSTIFY_RIGHT:
1993 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
1994 GINT_TO_POINTER(TRUE));
2001 if (buffer_format->cs.font) {
2002 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2003 GINT_TO_POINTER (buffer_format->font));
2005 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
2006 if (buffer_format->cs.bullet) {
2007 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
2008 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
2010 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
2012 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
2014 g_free (buffer_format);
2015 g_free (current_format);
2017 /* Check dimming rules */
2018 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2019 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
2023 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
2025 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2027 ModestWindowPrivate *parent_priv;
2028 ModestMsgEditWindowPrivate *priv;
2030 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2031 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2033 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
2034 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu");
2035 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2036 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
2038 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatPlainTextMenu");
2039 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2040 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
2043 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2045 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2046 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
2048 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2049 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
2051 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
2052 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
2055 switch (buffer_format->justification)
2057 case GTK_JUSTIFY_LEFT:
2058 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2060 case GTK_JUSTIFY_CENTER:
2061 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2063 case GTK_JUSTIFY_RIGHT:
2064 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2071 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
2073 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
2074 G_CALLBACK (modest_msg_edit_window_color_button_change),
2076 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
2077 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
2078 G_CALLBACK (modest_msg_edit_window_color_button_change),
2081 if (priv->current_size_index != buffer_format->font_size) {
2085 path = gtk_tree_path_new_from_indices (buffer_format->font_size, -1);
2086 if (gtk_tree_model_get_iter (priv->sizes_model, &iter, path)) {
2090 priv->current_size_index = buffer_format->font_size;
2092 gtk_tree_model_get (priv->sizes_model, &iter, 0, &size_text, -1);
2093 markup = g_strconcat ("<span font_family='Sans'>",
2094 size_text, "</span>", NULL);
2096 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2100 gtk_tree_path_free (path);
2103 if (priv->current_face_index != buffer_format->font) {
2107 path = gtk_tree_path_new_from_indices (buffer_format->font, -1);
2108 if (gtk_tree_model_get_iter (priv->faces_model, &iter, path)) {
2112 priv->current_face_index = buffer_format->font;
2113 gtk_tree_model_get (priv->faces_model, &iter, 0, &face_name, -1);
2114 markup = g_strconcat ("<span font_family='", face_name, "'>Tt</span>", NULL);
2115 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2122 g_free (buffer_format);
2126 #ifdef MODEST_HILDON_VERSION_0
2128 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2131 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2132 ModestMsgEditWindowPrivate *priv;
2133 GtkWidget *dialog = NULL;
2135 GdkColor *new_color = NULL;
2137 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2138 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2140 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2141 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2142 g_free (buffer_format);
2144 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2145 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2146 if (new_color != NULL) {
2147 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2148 (gpointer) new_color);
2151 gtk_widget_destroy (dialog);
2156 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2159 ModestMsgEditWindowPrivate *priv;
2160 GtkWidget *dialog = NULL;
2162 GdkColor *old_color = NULL;
2163 const GdkColor *new_color = NULL;
2165 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2166 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2168 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2169 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2171 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2172 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2173 if (new_color != NULL)
2174 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2176 gtk_widget_destroy (dialog);
2182 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2185 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2186 ModestMsgEditWindowPrivate *priv;
2187 GtkWidget *dialog = NULL;
2189 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2190 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2192 dialog = hildon_color_chooser_new ();
2193 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2194 g_free (buffer_format);
2196 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2198 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2199 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2202 gtk_widget_destroy (dialog);
2207 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2210 ModestMsgEditWindowPrivate *priv;
2211 GtkWidget *dialog = NULL;
2212 GdkColor *old_color = NULL;
2214 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2215 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2217 dialog = hildon_color_chooser_new ();
2218 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2220 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2222 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2223 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2225 gtk_widget_destroy (dialog);
2228 #endif /*!MODEST_HILDON_VERSION_0*/
2233 create_stream_for_uri (const gchar* uri)
2238 TnyStream *result = NULL;
2240 GnomeVFSHandle *handle = NULL;
2241 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2242 if (test == GNOME_VFS_OK) {
2243 TnyStream *vfssstream = TNY_STREAM (tny_vfs_stream_new (handle));
2244 /* Streams over OBEX (Bluetooth) are not seekable but
2245 * we expect them to be (we might need to read them
2246 * several times). So if this is a Bluetooth URI just
2247 * read the whole file into memory (this is not a fast
2248 * protocol so we can assume that these files are not
2249 * going to be very big) */
2250 if ((g_ascii_strncasecmp (uri, "obex://", 7) == 0)||
2251 (g_ascii_strncasecmp (uri, "upnpav://", 9) == 0)) {
2252 TnyStream *memstream = tny_camel_mem_stream_new ();
2253 tny_stream_write_to_stream (vfssstream, memstream);
2254 g_object_unref (vfssstream);
2257 result = vfssstream;
2265 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2268 ModestMsgEditWindowPrivate *priv;
2269 GtkWidget *dialog = NULL;
2271 GSList *uris = NULL;
2272 GSList *uri_node = NULL;
2274 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2276 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2277 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2278 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2280 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2282 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2283 GTK_WINDOW (dialog), GTK_WINDOW (window));
2285 response = gtk_dialog_run (GTK_DIALOG (dialog));
2287 case GTK_RESPONSE_OK:
2289 gchar *current_folder;
2290 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2291 current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
2292 if (current_folder && current_folder != '\0') {
2294 modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_INSERT_IMAGE_PATH,
2295 current_folder, &err);
2297 g_debug ("Error storing latest used folder: %s", err->message);
2301 g_free (current_folder);
2307 gtk_widget_destroy (dialog);
2309 g_object_ref (window);
2310 /* The operation could take some time so allow the dialog to be closed */
2311 while (gtk_events_pending ())
2312 gtk_main_iteration ();
2314 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2316 GnomeVFSHandle *handle = NULL;
2317 GnomeVFSResult result;
2318 GtkTextIter position;
2319 GtkTextMark *insert_mark;
2321 uri = (const gchar *) uri_node->data;
2322 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2323 if (result == GNOME_VFS_OK) {
2325 GnomeVFSFileInfo *info;
2326 gchar *filename, *basename, *escaped_filename;
2327 TnyMimePart *mime_part;
2329 const gchar *mime_type = NULL;
2330 GnomeVFSURI *vfs_uri;
2331 guint64 stream_size;
2333 gnome_vfs_close (handle);
2334 vfs_uri = gnome_vfs_uri_new (uri);
2336 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2337 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2338 g_free (escaped_filename);
2339 gnome_vfs_uri_unref (vfs_uri);
2340 info = gnome_vfs_file_info_new ();
2342 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2343 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2345 mime_type = gnome_vfs_file_info_get_mime_type (info);
2347 mime_part = tny_platform_factory_new_mime_part
2348 (modest_runtime_get_platform_factory ());
2350 TnyStream *stream = create_stream_for_uri (uri);
2352 if (stream == NULL) {
2354 modest_platform_information_banner (NULL, NULL,
2355 _FM("sfil_ib_opening_not_allowed"));
2357 g_object_unref (mime_part);
2358 gnome_vfs_file_info_unref (info);
2362 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2364 content_id = g_strdup_printf ("%d", priv->next_cid);
2365 tny_mime_part_set_content_id (mime_part, content_id);
2366 g_free (content_id);
2369 basename = g_path_get_basename (filename);
2370 tny_mime_part_set_filename (mime_part, basename);
2373 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size, window);
2375 if (pixbuf != NULL) {
2376 priv->images_size += stream_size;
2377 priv->images_count ++;
2378 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2379 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2380 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position,
2381 tny_mime_part_get_content_id (mime_part), pixbuf);
2382 g_object_unref (pixbuf);
2384 tny_list_prepend (priv->images, (GObject *) mime_part);
2385 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2387 modest_platform_information_banner (NULL, NULL,
2388 _("mail_ib_file_operation_failed"));
2392 g_object_unref (mime_part);
2393 gnome_vfs_file_info_unref (info);
2397 g_object_unref (window);
2401 on_attach_file_response (GtkDialog *dialog,
2405 GSList *uris = NULL;
2407 GnomeVFSFileSize total_size, allowed_size;
2408 ModestMsgEditWindow *window;
2409 ModestMsgEditWindowPrivate *priv;
2414 case GTK_RESPONSE_OK:
2416 gchar *current_folder;
2418 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2419 current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
2420 if (current_folder && current_folder != '\0') {
2422 modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_ATTACH_FILE_PATH,
2423 current_folder, &err);
2425 g_debug ("Error storing latest used folder: %s", err->message);
2429 g_free (current_folder);
2436 window = MODEST_MSG_EDIT_WINDOW (user_data);
2437 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2439 /* allowed size is the maximum size - what's already there */
2440 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2441 &att_num, &att_size);
2442 allowed_size = MODEST_MAX_ATTACHMENT_SIZE - att_size;
2445 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2447 const gchar *uri = (const gchar *) uri_node->data;
2450 modest_msg_edit_window_attach_file_one (window, uri, allowed_size);
2452 if (total_size > allowed_size) {
2453 g_warning ("%s: total size: %u",
2454 __FUNCTION__, (unsigned int)total_size);
2457 allowed_size -= total_size;
2459 g_slist_foreach (uris, (GFunc) g_free, NULL);
2460 g_slist_free (uris);
2462 gtk_widget_destroy (GTK_WIDGET (dialog));
2466 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2468 GtkWidget *dialog = NULL;
2469 ModestMsgEditWindowPrivate *priv;
2472 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(window));
2474 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2476 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2479 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window),
2480 GTK_FILE_CHOOSER_ACTION_OPEN);
2481 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2482 conf_folder = modest_conf_get_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_ATTACH_FILE_PATH, NULL);
2483 if (conf_folder && conf_folder[0] != '\0') {
2484 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), conf_folder);
2487 /* Set the default folder to images folder */
2488 docs_folder = g_build_filename (g_getenv (MODEST_MAEMO_UTILS_MYDOCS_ENV),
2489 ".documents", NULL);
2490 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), docs_folder);
2491 g_free (docs_folder);
2493 g_free (conf_folder);
2494 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2495 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2496 GTK_WINDOW (dialog), GTK_WINDOW (window));
2498 /* Connect to response & show */
2499 g_signal_connect (dialog, "response",
2500 G_CALLBACK (on_attach_file_response), window);
2501 gtk_widget_show (dialog);
2506 modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window,
2508 GnomeVFSFileSize allowed_size)
2511 GnomeVFSHandle *handle = NULL;
2512 ModestMsgEditWindowPrivate *priv;
2513 GnomeVFSResult result;
2514 GnomeVFSFileSize size = 0;
2515 g_return_val_if_fail (window, 0);
2516 g_return_val_if_fail (uri, 0);
2518 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2520 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2521 if (result == GNOME_VFS_OK) {
2522 TnyMimePart *mime_part;
2524 const gchar *mime_type = NULL;
2526 gchar *escaped_filename;
2529 GnomeVFSFileInfo *info;
2530 GnomeVFSURI *vfs_uri;
2532 gnome_vfs_close (handle);
2533 vfs_uri = gnome_vfs_uri_new (uri);
2536 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2537 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2538 g_free (escaped_filename);
2539 gnome_vfs_uri_unref (vfs_uri);
2541 info = gnome_vfs_file_info_new ();
2543 if (gnome_vfs_get_file_info (uri,
2545 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2547 mime_type = gnome_vfs_file_info_get_mime_type (info);
2548 mime_part = tny_platform_factory_new_mime_part
2549 (modest_runtime_get_platform_factory ());
2551 /* try to get the attachment's size; this may fail for weird
2552 * file systems, like obex, upnp... */
2553 if (allowed_size != 0 &&
2554 info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
2556 if (size > allowed_size) {
2557 modest_platform_information_banner (NULL, NULL,
2558 _FM("sfil_ib_opening_not_allowed"));
2563 g_warning ("%s: could not get attachment size", __FUNCTION__);
2565 stream = create_stream_for_uri (uri);
2567 if (stream == NULL) {
2569 modest_platform_information_banner (NULL, NULL, _FM("sfil_ib_opening_not_allowed"));
2571 g_object_unref (mime_part);
2573 gnome_vfs_file_info_unref (info);
2577 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2578 g_object_unref (stream);
2580 content_id = g_strdup_printf ("%d", priv->next_cid);
2581 tny_mime_part_set_content_id (mime_part, content_id);
2582 g_free (content_id);
2585 basename = g_path_get_basename (filename);
2586 tny_mime_part_set_filename (mime_part, basename);
2589 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2590 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2592 info->size == 0, info->size);
2593 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2594 gtk_widget_show_all (priv->attachments_caption);
2595 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2597 g_object_unref (mime_part);
2598 gnome_vfs_file_info_unref (info);
2605 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2608 ModestMsgEditWindowPrivate *priv;
2611 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2612 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2614 if (att_list == NULL) {
2615 att_list = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2616 if (!modest_maemo_utils_select_attachments (GTK_WINDOW (window), att_list, TRUE)) {
2617 g_object_unref (att_list);
2622 g_object_ref (att_list);
2625 if (tny_list_get_length (att_list) == 0) {
2626 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2628 gboolean dialog_response;
2629 gchar *message = NULL;
2630 gchar *filename = NULL;
2632 if (tny_list_get_length (att_list) == 1) {
2634 iter = tny_list_create_iterator (att_list);
2635 part = (TnyMimePart *) tny_iterator_get_current (iter);
2636 g_object_unref (iter);
2637 if (TNY_IS_MSG (part)) {
2638 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2640 filename = tny_header_dup_subject (header);
2641 g_object_unref (header);
2643 if (filename == NULL) {
2644 filename = g_strdup (_("mail_va_no_subject"));
2647 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2649 g_object_unref (part);
2651 filename = g_strdup ("");
2653 message = g_strdup_printf (ngettext("emev_nc_delete_attachment",
2654 "emev_nc_delete_attachments",
2655 tny_list_get_length (att_list)), filename);
2658 dialog_response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
2662 if (dialog_response != GTK_RESPONSE_OK) {
2663 g_object_unref (att_list);
2667 for (iter = tny_list_create_iterator (att_list);
2668 !tny_iterator_is_done (iter);
2669 tny_iterator_next (iter)) {
2670 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2671 const gchar *att_id;
2672 tny_list_remove (priv->attachments, (GObject *) mime_part);
2674 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2676 if (tny_list_get_length (priv->attachments) == 0)
2677 gtk_widget_hide (priv->attachments_caption);
2678 att_id = tny_mime_part_get_content_id (mime_part);
2680 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2682 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2683 g_object_unref (mime_part);
2685 g_object_unref (iter);
2688 g_object_unref (att_list);
2690 /* if the last attachment has been removed, focus the Subject: field */
2691 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2692 gtk_widget_grab_focus (priv->subject_field);
2696 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2699 ModestMsgEditWindowPrivate *priv;
2700 GdkColor *new_color;
2701 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2703 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2704 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2707 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2709 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2711 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2713 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2718 font_size_clicked (GtkToolButton *button,
2719 ModestMsgEditWindow *window)
2721 ModestMsgEditWindowPrivate *priv;
2722 GtkWidget *selector, *dialog;
2724 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2726 selector = hildon_touch_selector_new ();
2727 hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector), priv->sizes_model, TRUE);
2728 hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, priv->current_size_index);
2730 dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
2731 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog), HILDON_TOUCH_SELECTOR (selector));
2732 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_font_size"));
2734 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2738 WPTextBufferFormat format;
2740 new_index = hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (selector), 0);
2742 memset (&format, 0, sizeof (format));
2743 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2745 format.cs.font_size = TRUE;
2746 format.cs.text_position = TRUE;
2747 format.cs.font = TRUE;
2748 format.font_size = new_index;
2749 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2751 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2752 GINT_TO_POINTER (new_index)))
2753 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2755 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2756 size_text = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector));
2757 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
2758 size_text, "</span>", NULL);
2760 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2764 gtk_widget_destroy (dialog);
2766 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2771 font_face_clicked (GtkToolButton *button,
2772 ModestMsgEditWindow *window)
2774 ModestMsgEditWindowPrivate *priv;
2775 GtkWidget *selector, *dialog;
2776 GtkCellRenderer *renderer;
2778 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2780 selector = hildon_touch_selector_new ();
2781 renderer = gtk_cell_renderer_text_new ();
2782 g_object_set (G_OBJECT (renderer), "alignment", PANGO_ALIGN_CENTER, "xalign", 0.5, NULL);
2783 hildon_touch_selector_append_column (HILDON_TOUCH_SELECTOR (selector), priv->faces_model,
2784 renderer, "family", 0, "text", 0, NULL);
2785 hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, priv->current_face_index);
2787 dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
2788 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog), HILDON_TOUCH_SELECTOR (selector));
2789 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_font_face"));
2791 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2792 gint new_font_index;
2796 new_font_index = hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (selector), 0);
2797 path = gtk_tree_path_new_from_indices (new_font_index, -1);
2798 if (gtk_tree_model_get_iter (priv->faces_model, &iter, path)) {
2802 gtk_tree_model_get (priv->faces_model, &iter, 0, &face_name, -1);
2804 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2805 GINT_TO_POINTER(new_font_index)))
2806 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2808 markup = g_strconcat ("<span font_family='", face_name, "'>Tt</span>", NULL);
2809 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2811 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2815 gtk_tree_path_free (path);
2818 gtk_widget_destroy (dialog);
2820 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2825 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2828 ModestMsgEditWindowPrivate *priv = NULL;
2829 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2831 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2832 if (!priv->update_caption_visibility)
2835 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2837 gtk_widget_show (priv->cc_caption);
2839 gtk_widget_hide (priv->cc_caption);
2841 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2845 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2848 ModestMsgEditWindowPrivate *priv = NULL;
2849 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2851 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2852 if (!priv->update_caption_visibility)
2855 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2857 gtk_widget_show (priv->bcc_caption);
2859 gtk_widget_hide (priv->bcc_caption);
2861 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2865 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2866 ModestRecptEditor *editor)
2868 ModestMsgEditWindowPrivate *priv;
2870 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2871 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2873 /* we check for low-mem; in that case, show a warning, and don't allow
2874 * for the addressbook
2876 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2879 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2881 if (editor == NULL) {
2882 GtkWidget *view_focus;
2883 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2885 /* This code should be kept in sync with ModestRecptEditor. The
2886 textview inside the recpt editor is the one that really gets the
2887 focus. As it's inside a scrolled window, and this one inside the
2888 hbox recpt editor inherits from, we'll need to go up in the
2889 hierarchy to know if the text view is part of the recpt editor
2890 or if it's a different text entry */
2892 if (gtk_widget_get_parent (view_focus)) {
2893 GtkWidget *first_parent;
2895 first_parent = gtk_widget_get_parent (view_focus);
2896 if (gtk_widget_get_parent (first_parent) &&
2897 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2898 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2903 editor = MODEST_RECPT_EDITOR (priv->to_field);
2907 modest_address_book_select_addresses (editor);
2912 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2914 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2916 modest_msg_edit_window_open_addressbook (window, NULL);
2920 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2921 gboolean show_toolbar)
2923 ModestWindowPrivate *parent_priv;
2925 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2926 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2928 /* We can not just use the code of
2929 modest_msg_edit_window_setup_toolbar because it has a
2930 mixture of both initialization and creation code. */
2932 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2934 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2938 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2939 TnyHeaderFlags priority_flags)
2941 ModestMsgEditWindowPrivate *priv;
2942 ModestWindowPrivate *parent_priv;
2944 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2946 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2947 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2949 if (priv->priority_flags != priority_flags) {
2950 GtkAction *priority_action = NULL;
2952 priv->priority_flags = priority_flags;
2954 switch (priority_flags) {
2955 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2956 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2957 MODEST_HEADER_ICON_HIGH,
2958 HILDON_ICON_SIZE_SMALL);
2959 gtk_widget_show (priv->priority_icon);
2960 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2961 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2963 case TNY_HEADER_FLAG_LOW_PRIORITY:
2964 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2965 MODEST_HEADER_ICON_LOW,
2966 HILDON_ICON_SIZE_SMALL);
2967 gtk_widget_show (priv->priority_icon);
2968 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2969 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2972 gtk_widget_hide (priv->priority_icon);
2973 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2974 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2977 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2978 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2980 gtk_widget_queue_resize (priv->subject_box);
2984 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2987 ModestMsgEditWindowPrivate *priv;
2988 ModestWindowPrivate *parent_priv;
2989 gint current_format;
2991 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2993 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2994 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2996 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2997 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2999 if (current_format != file_format) {
3000 switch (file_format) {
3001 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
3002 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
3003 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
3005 case MODEST_FILE_FORMAT_PLAIN_TEXT:
3009 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
3010 response = gtk_dialog_run (GTK_DIALOG (dialog));
3011 gtk_widget_destroy (dialog);
3012 if (response == GTK_RESPONSE_OK) {
3013 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
3015 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu"));
3016 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
3021 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3022 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3023 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
3028 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
3031 ModestMsgEditWindowPrivate *priv;
3032 WPTextBufferFormat oldfmt, fmt;
3033 gint old_position = 0;
3037 GdkColor *color = NULL;
3038 gboolean bold, bold_set, italic, italic_set;
3039 gboolean underline, underline_set;
3040 gboolean strikethrough, strikethrough_set;
3041 gboolean position_set;
3042 gboolean font_size_set, font_set, color_set;
3045 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3046 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3048 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
3049 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(),
3050 GTK_WINDOW(dialog), GTK_WINDOW (window));
3052 /* First we get the currently selected font information */
3053 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
3055 switch (oldfmt.text_position) {
3056 case TEXT_POSITION_NORMAL:
3059 case TEXT_POSITION_SUPERSCRIPT:
3067 g_object_set (G_OBJECT (dialog),
3068 "bold", oldfmt.bold != FALSE,
3069 "bold-set", !oldfmt.cs.bold,
3070 "underline", oldfmt.underline != FALSE,
3071 "underline-set", !oldfmt.cs.underline,
3072 "italic", oldfmt.italic != FALSE,
3073 "italic-set", !oldfmt.cs.italic,
3074 "strikethrough", oldfmt.strikethrough != FALSE,
3075 "strikethrough-set", !oldfmt.cs.strikethrough,
3076 "color", &oldfmt.color,
3077 "color-set", !oldfmt.cs.color,
3078 "size", wp_font_size[oldfmt.font_size],
3079 "size-set", !oldfmt.cs.font_size,
3080 "position", old_position,
3081 "position-set", !oldfmt.cs.text_position,
3082 "family", wp_get_font_name (oldfmt.font),
3083 "family-set", !oldfmt.cs.font,
3086 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
3087 GTK_WINDOW (dialog), GTK_WINDOW (window));
3088 gtk_widget_show_all (dialog);
3089 priv->font_dialog = dialog;
3090 response = gtk_dialog_run (GTK_DIALOG (dialog));
3091 priv->font_dialog = NULL;
3092 if (response == GTK_RESPONSE_OK) {
3094 g_object_get( dialog,
3096 "bold-set", &bold_set,
3097 "underline", &underline,
3098 "underline-set", &underline_set,
3100 "italic-set", &italic_set,
3101 "strikethrough", &strikethrough,
3102 "strikethrough-set", &strikethrough_set,
3104 "color-set", &color_set,
3106 "size-set", &font_size_set,
3107 "family", &font_name,
3108 "family-set", &font_set,
3109 "position", &position,
3110 "position-set", &position_set,
3115 if (response == GTK_RESPONSE_OK) {
3116 memset(&fmt, 0, sizeof(fmt));
3122 fmt.italic = italic;
3123 fmt.cs.italic = TRUE;
3125 if (underline_set) {
3126 fmt.underline = underline;
3127 fmt.cs.underline = TRUE;
3129 if (strikethrough_set) {
3130 fmt.strikethrough = strikethrough;
3131 fmt.cs.strikethrough = TRUE;
3136 ? TEXT_POSITION_NORMAL
3137 : ( ( position == 1 )
3138 ? TEXT_POSITION_SUPERSCRIPT
3139 : TEXT_POSITION_SUBSCRIPT );
3140 fmt.cs.text_position = TRUE;
3141 fmt.font_size = oldfmt.font_size;
3145 fmt.cs.color = TRUE;
3148 fmt.font = wp_get_font_index(font_name,
3153 if (font_size_set) {
3154 fmt.cs.font_size = TRUE;
3155 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
3157 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
3158 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
3160 gtk_widget_destroy (dialog);
3162 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
3166 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
3168 ModestMsgEditWindowPrivate *priv;
3170 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3171 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3173 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
3175 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3176 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3180 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
3182 ModestMsgEditWindowPrivate *priv;
3184 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3185 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3187 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
3189 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3190 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3195 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
3197 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3199 priv->can_undo = can_undo;
3203 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
3205 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3207 priv->can_redo = can_redo;
3211 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
3213 ModestMsgEditWindowPrivate *priv;
3214 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3215 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3217 return priv->can_undo;
3221 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
3223 ModestMsgEditWindowPrivate *priv;
3224 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3225 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3227 return priv->can_redo;
3232 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
3235 GtkTextIter match_start, match_end;
3237 if (image_id == NULL)
3240 gtk_text_buffer_get_start_iter (buffer, &iter);
3242 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
3243 GSList *tags = gtk_text_iter_get_tags (&match_start);
3245 for (node = tags; node != NULL; node = g_slist_next (node)) {
3246 GtkTextTag *tag = (GtkTextTag *) node->data;
3247 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
3248 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
3249 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
3251 offset = gtk_text_iter_get_offset (&match_start);
3252 gtk_text_buffer_delete (buffer, &match_start, &match_end);
3253 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
3257 gtk_text_iter_forward_char (&iter);
3262 message_is_empty (ModestMsgEditWindow *window)
3264 ModestMsgEditWindowPrivate *priv = NULL;
3266 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3267 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3269 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
3270 * so we can ignore markup.
3272 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
3275 count = gtk_text_buffer_get_char_count (buf);
3281 msg_body_focus (GtkWidget *focus,
3282 GdkEventFocus *event,
3286 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3287 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3288 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3293 recpt_field_changed (GtkTextBuffer *buffer,
3294 ModestMsgEditWindow *editor)
3296 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3297 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3301 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3303 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3304 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3308 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3311 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3312 GtkTextBuffer *buffer;
3314 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3315 gtk_text_buffer_set_modified (buffer, modified);
3316 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3317 gtk_text_buffer_set_modified (buffer, modified);
3318 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3319 gtk_text_buffer_set_modified (buffer, modified);
3320 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3324 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3326 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3327 const char *account_name;
3328 GtkTextBuffer *buffer;
3330 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3331 if (gtk_text_buffer_get_modified (buffer))
3333 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3334 if (gtk_text_buffer_get_modified (buffer))
3336 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3337 if (gtk_text_buffer_get_modified (buffer))
3339 if (gtk_text_buffer_get_modified (priv->text_buffer))
3342 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3343 if (priv->original_mailbox) {
3344 if (!account_name || strcmp (account_name, priv->original_mailbox))
3346 } else if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3357 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3359 ModestMsgEditWindowPrivate *priv = NULL;
3361 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3362 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3364 /* check if there's no recipient added */
3365 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3366 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3367 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3368 /* no recipient contents, then select contacts */
3369 modest_msg_edit_window_open_addressbook (window, NULL);
3373 g_object_ref (window);
3374 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3375 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3376 g_object_unref (window);
3379 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3380 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3381 g_object_unref (window);
3384 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3385 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3386 g_object_unref (window);
3390 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3391 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3392 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3393 g_object_unref (window);
3400 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3401 ModestMsgEditWindow *window)
3403 modest_msg_edit_window_offer_attach_file (window);
3407 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3409 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3411 return priv->clipboard_text;
3415 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3417 ModestMsgEditWindow *window)
3419 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3420 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3423 /* It could happen that the window was already closed */
3424 if (!GTK_WIDGET_VISIBLE (window))
3427 g_object_ref (window);
3428 text = gtk_clipboard_wait_for_text (selection_clipboard);
3430 if (priv->clipboard_text != NULL) {
3431 g_free (priv->clipboard_text);
3433 priv->clipboard_text = text;
3435 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3437 g_object_unref (window);
3440 static gboolean clipboard_owner_change_idle (gpointer userdata)
3442 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
3443 ModestMsgEditWindowPrivate *priv;
3445 gdk_threads_enter ();
3446 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3447 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3449 priv->clipboard_owner_idle = 0;
3450 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, window);
3451 gdk_threads_leave ();
3457 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window)
3459 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3460 if (priv->clipboard_owner_idle == 0) {
3461 priv->clipboard_owner_idle = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
3462 clipboard_owner_change_idle,
3463 g_object_ref (window),
3469 subject_field_move_cursor (GtkEntry *entry,
3470 GtkMovementStep step,
3475 /* It could happen that the window was already closed */
3476 if (!GTK_WIDGET_VISIBLE (window))
3479 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3483 update_window_title (ModestMsgEditWindow *window)
3485 ModestMsgEditWindowPrivate *priv = NULL;
3486 const gchar *subject;
3488 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3489 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3490 if (subject == NULL || subject[0] == '\0')
3491 subject = _("mail_va_new_email");
3493 gtk_window_set_title (GTK_WINDOW (window), subject);
3498 subject_field_changed (GtkEditable *editable,
3499 ModestMsgEditWindow *window)
3501 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3502 update_window_title (window);
3503 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3504 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3505 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3509 subject_field_insert_text (GtkEditable *editable,
3511 gint new_text_length,
3513 ModestMsgEditWindow *window)
3515 GString *result = g_string_new ("");
3517 gint result_len = 0;
3518 const gchar *entry_text = NULL;
3521 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3522 old_length = g_utf8_strlen (entry_text, -1);
3524 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3525 gunichar c = g_utf8_get_char_validated (current, 8);
3526 /* Invalid unichar, stop */
3532 result = g_string_append_unichar (result, c);
3536 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3537 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3540 /* Prevent endless recursion */
3541 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3542 g_signal_emit_by_name (editable, "insert-text",
3543 (gpointer) result->str, (gpointer) result->len,
3544 (gpointer) position, (gpointer) window);
3545 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3549 if (result_len + old_length > 1000) {
3550 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3551 _CS("ckdg_ib_maximum_characters_reached"));
3553 g_string_free (result, TRUE);
3557 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3560 ModestMsgEditWindowPrivate *priv = NULL;
3562 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3563 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3565 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3568 gtk_widget_show_all (priv->find_toolbar);
3569 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3571 gtk_widget_hide_all (priv->find_toolbar);
3572 gtk_widget_grab_focus (priv->msg_body);
3577 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3579 GtkTextIter *match_start,
3580 GtkTextIter *match_end)
3582 GtkTextIter end_iter;
3583 gchar *str_casefold;
3586 gchar *range_casefold;
3589 gboolean result = FALSE;
3596 gtk_text_iter_forward_to_end (&end_iter);
3598 str_casefold = g_utf8_casefold (str, -1);
3599 str_chars_n = strlen (str);
3601 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3602 range_casefold = g_utf8_casefold (range_text, -1);
3603 range_chars_n = strlen (range_casefold);
3605 if (range_chars_n < str_chars_n) {
3606 g_free (str_casefold);
3607 g_free (range_text);
3608 g_free (range_casefold);
3612 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3613 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3614 if (!g_utf8_collate (range_subtext, str_casefold)) {
3615 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3617 if (!gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3618 match_start, match_end, NULL)) {
3619 g_warning ("Matched string with collate, but not matched in model");
3621 g_free (found_text);
3623 g_free (range_subtext);
3627 g_free (str_casefold);
3628 g_free (range_text);
3629 g_free (range_casefold);
3636 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3637 ModestMsgEditWindow *window)
3639 gchar *current_search = NULL;
3640 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3642 GtkTextIter selection_start, selection_end;
3643 GtkTextIter match_start, match_end;
3644 gboolean continue_search = FALSE;
3646 if (message_is_empty (window)) {
3647 g_free (priv->last_search);
3648 priv->last_search = NULL;
3649 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3653 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3654 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3655 g_free (current_search);
3656 g_free (priv->last_search);
3657 priv->last_search = NULL;
3658 /* Information banner about empty search */
3659 hildon_banner_show_information (NULL, NULL, _CS("ecdg_ib_find_rep_enter_text"));
3663 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3664 continue_search = TRUE;
3666 g_free (priv->last_search);
3667 priv->last_search = g_strdup (current_search);
3670 if (continue_search) {
3671 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3672 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3673 &match_start, &match_end);
3675 hildon_banner_show_information (NULL, NULL, _HL("ckct_ib_find_search_complete"));
3677 GtkTextIter buffer_start;
3678 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3679 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3680 &match_start, &match_end);
3682 hildon_banner_show_information (NULL, NULL, _HL("ckct_ib_find_no_matches"));
3685 /* Mark as selected the string found in search */
3687 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3688 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3689 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3691 g_free (priv->last_search);
3692 priv->last_search = NULL;
3694 g_free (current_search);
3698 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3700 ModestMsgEditWindowPrivate *priv;
3702 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3707 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3710 ModestMsgEditWindowPrivate *priv;
3712 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3717 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3718 ModestMsgEditWindow *window)
3720 modest_msg_edit_window_toggle_find_toolbar (window, FALSE);
3724 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3727 ModestMsgEditWindowPrivate *priv;
3728 TnyHeader *header = NULL;
3730 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3731 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3733 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3735 if (priv->draft_msg != NULL) {
3736 g_object_unref (priv->draft_msg);
3739 if (draft != NULL) {
3740 g_object_ref (draft);
3741 header = tny_msg_get_header (draft);
3742 if (priv->msg_uid) {
3743 g_free (priv->msg_uid);
3744 priv->msg_uid = NULL;
3746 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3749 priv->draft_msg = draft;
3753 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3754 GtkTextIter *start, GtkTextIter *end,
3757 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3758 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3761 if (tag == NULL) return;
3762 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3763 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3764 replace_with_images (window, priv->images);
3769 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3772 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3774 g_return_if_fail (TNY_IS_MIME_PART (part));
3775 tny_list_prepend (priv->attachments, (GObject *) part);
3776 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3777 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3778 gtk_widget_show_all (priv->attachments_caption);
3779 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3783 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3785 ModestMsgEditWindowPrivate *priv;
3787 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3788 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3790 return priv->msg_uid;
3794 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3795 ModestMsgEditWindowWidgetType widget_type)
3797 ModestMsgEditWindowPrivate *priv;
3799 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3800 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3802 switch (widget_type) {
3803 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3804 return priv->msg_body;
3806 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3807 return priv->to_field;
3809 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3810 return priv->cc_field;
3812 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3813 return priv->bcc_field;
3815 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3816 return priv->subject_field;
3818 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3819 return priv->attachments_view;
3827 remove_tags (WPTextBuffer *buffer)
3829 GtkTextIter start, end;
3831 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3832 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3834 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3838 on_account_removed (TnyAccountStore *account_store,
3839 TnyAccount *account,
3842 /* Do nothing if it's a store account, because we use the
3843 transport to send the messages */
3844 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3845 const gchar *parent_acc = NULL;
3846 const gchar *our_acc = NULL;
3848 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3849 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3850 /* Close this window if I'm showing a message of the removed account */
3851 if (strcmp (parent_acc, our_acc) == 0)
3852 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3856 static void update_signature (ModestMsgEditWindow *self,
3857 const gchar *old_account,
3858 const gchar *new_account)
3860 ModestMsgEditWindowPrivate *priv;
3861 gboolean has_old_signature, has_new_signature;
3863 GtkTextIter match_start, match_end;
3864 ModestAccountMgr *mgr;
3866 gchar *full_signature;
3868 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
3870 gtk_text_buffer_begin_user_action (priv->text_buffer);
3872 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
3873 mgr = modest_runtime_get_account_mgr ();
3877 signature = modest_account_mgr_get_signature_from_recipient (mgr, old_account, &has_old_signature);
3878 if (has_old_signature) {
3879 full_signature = g_strconcat ("\n--\n", signature, NULL);
3880 if (gtk_text_iter_forward_search (&iter, full_signature, 0, &match_start, &match_end, NULL)) {
3881 gtk_text_buffer_delete (priv->text_buffer, &match_start, &match_end);
3883 } else if (gtk_text_iter_forward_search (&iter, _("mcen_ia_editor_original_message"), 0,
3884 &match_start, &match_end, NULL)) {
3887 g_free (full_signature);
3892 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3893 signature = modest_account_mgr_get_signature_from_recipient (mgr, new_account, &has_new_signature);
3894 if (has_new_signature) {
3895 full_signature = g_strconcat ("\n--\n", signature, NULL);
3896 gtk_text_buffer_insert (priv->text_buffer, &iter, full_signature, -1);
3897 g_free (full_signature);
3900 gtk_text_buffer_end_user_action (priv->text_buffer);
3904 from_field_changed (HildonPickerButton *button,
3905 ModestMsgEditWindow *self)
3907 ModestMsgEditWindowPrivate *priv;
3908 gchar *old_account, *new_account;
3910 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
3912 old_account = priv->last_from_account;
3913 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3914 new_account = priv->last_from_account;
3916 update_signature (self, old_account, new_account);
3920 typedef struct _MessageSettingsHelper {
3921 ModestMsgEditWindow *window;
3922 GSList *priority_group;
3923 GSList *format_group;
3924 GtkToggleButton *current_priority;
3925 GtkToggleButton *current_format;
3926 } MessageSettingsHelper;
3929 on_priority_toggle (GtkToggleButton *button,
3930 MessageSettingsHelper *helper)
3933 ModestMsgEditWindowPrivate *priv;
3935 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (helper->window);
3936 if (gtk_toggle_button_get_active (button)) {
3938 for (node = helper->priority_group; node != NULL; node = g_slist_next (node)) {
3939 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3940 if ((node_button != button) &&
3941 gtk_toggle_button_get_active (node_button)) {
3942 gtk_toggle_button_set_active (node_button, FALSE);
3945 helper->current_priority = button;
3947 gboolean found = FALSE;
3948 /* If no one is active, activate it again */
3949 for (node = helper->priority_group; node != NULL; node = g_slist_next (node)) {
3950 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3951 if (gtk_toggle_button_get_active (node_button)) {
3957 gtk_toggle_button_set_active (button, TRUE);
3963 on_format_toggle (GtkToggleButton *button,
3964 MessageSettingsHelper *helper)
3967 ModestMsgEditWindowPrivate *priv;
3969 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (helper->window);
3970 if (gtk_toggle_button_get_active (button)) {
3972 for (node = helper->format_group; node != NULL; node = g_slist_next (node)) {
3973 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3974 if ((node_button != button) &&
3975 gtk_toggle_button_get_active (node_button)) {
3976 gtk_toggle_button_set_active (node_button, FALSE);
3979 helper->current_format = button;
3981 gboolean found = FALSE;
3982 /* If no one is active, activate it again */
3983 for (node = helper->format_group; node != NULL; node = g_slist_next (node)) {
3984 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3985 if (gtk_toggle_button_get_active (node_button)) {
3991 gtk_toggle_button_set_active (button, TRUE);
3998 modest_msg_edit_window_show_msg_settings_dialog (ModestMsgEditWindow *window)
4003 GtkWidget *priority_hbox;
4004 GtkWidget *high_toggle, *medium_toggle, *low_toggle;
4005 GtkWidget *captioned;
4006 GtkSizeGroup *title_sizegroup, *value_sizegroup;
4007 GtkWidget *format_hbox;
4008 GtkWidget *html_toggle, *text_toggle;
4009 ModestMsgEditWindowPrivate *priv;
4010 MessageSettingsHelper helper = {0,};
4012 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4013 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
4014 helper.window = window;
4015 helper.priority_group = NULL;
4016 helper.format_group = NULL;
4018 title_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4019 value_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4021 dialog = gtk_dialog_new_with_buttons (_("mcen_me_message_settings"), NULL,
4022 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
4023 _HL("wdgt_bd_done"), GTK_RESPONSE_ACCEPT, NULL);
4024 vbox = gtk_vbox_new (FALSE, 0);
4025 align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
4026 gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE, 0);
4027 gtk_container_add (GTK_CONTAINER (align), vbox);
4028 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), align);
4029 gtk_widget_show (align);
4030 gtk_widget_show (vbox);
4032 /* Priority toggles */
4033 priority_hbox = gtk_hbox_new (TRUE, 0);
4034 high_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4035 gtk_button_set_label (GTK_BUTTON (high_toggle), _("mcen_me_editor_priority_high"));
4036 helper.priority_group = g_slist_prepend (helper.priority_group, high_toggle);
4037 g_object_set_data (G_OBJECT (high_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_HIGH_PRIORITY));
4038 medium_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4039 gtk_button_set_label (GTK_BUTTON (medium_toggle), _("mcen_me_editor_priority_normal"));
4040 helper.priority_group = g_slist_prepend (helper.priority_group, medium_toggle);
4041 g_object_set_data (G_OBJECT (medium_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_NORMAL_PRIORITY));
4042 low_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4043 gtk_button_set_label (GTK_BUTTON (low_toggle), _("mcen_me_editor_priority_low"));
4044 helper.priority_group = g_slist_prepend (helper.priority_group, low_toggle);
4045 g_object_set_data (G_OBJECT (low_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_LOW_PRIORITY));
4046 gtk_box_pack_start (GTK_BOX (priority_hbox), low_toggle, TRUE, TRUE, 0);
4047 gtk_box_pack_start (GTK_BOX (priority_hbox), medium_toggle, TRUE, TRUE, 0);
4048 gtk_box_pack_start (GTK_BOX (priority_hbox), high_toggle, TRUE, TRUE, 0);
4049 gtk_widget_show_all (priority_hbox);
4050 captioned = modest_maemo_utils_create_captioned (title_sizegroup, value_sizegroup,
4051 _("mcen_me_editor_message_priority"), FALSE, priority_hbox);
4052 gtk_widget_show (captioned);
4053 gtk_box_pack_start (GTK_BOX (vbox), captioned, FALSE, FALSE, 0);
4055 /* format toggles */
4056 format_hbox = gtk_hbox_new (TRUE, 0);
4057 html_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4058 gtk_button_set_label (GTK_BUTTON (html_toggle), _("mcen_me_editor_formatted_text"));
4059 helper.format_group = g_slist_prepend (helper.format_group, html_toggle);
4060 g_object_set_data (G_OBJECT (html_toggle), "format", GINT_TO_POINTER (MODEST_MSG_EDIT_FORMAT_HTML));
4061 g_object_set_data (G_OBJECT (html_toggle), "file-format", GINT_TO_POINTER (MODEST_FILE_FORMAT_FORMATTED_TEXT));
4062 text_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4063 gtk_button_set_label (GTK_BUTTON (text_toggle), _("mcen_me_editor_plain_text"));
4064 helper.format_group = g_slist_prepend (helper.format_group, text_toggle);
4065 g_object_set_data (G_OBJECT (text_toggle), "format", GINT_TO_POINTER (MODEST_MSG_EDIT_FORMAT_TEXT));
4066 g_object_set_data (G_OBJECT (text_toggle), "file-format", GINT_TO_POINTER (MODEST_FILE_FORMAT_PLAIN_TEXT));
4067 gtk_box_pack_start (GTK_BOX (format_hbox), html_toggle, TRUE, TRUE, 0);
4068 gtk_box_pack_start (GTK_BOX (format_hbox), text_toggle, TRUE, TRUE, 0);
4069 gtk_widget_show_all (format_hbox);
4070 gtk_widget_show (format_hbox);
4071 gtk_box_pack_start (GTK_BOX (vbox), format_hbox, FALSE, FALSE, 0);
4074 g_object_unref (title_sizegroup);
4075 g_object_unref (value_sizegroup);
4077 /* Set current values */
4078 switch (priv->priority_flags) {
4079 case TNY_HEADER_FLAG_HIGH_PRIORITY:
4080 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (high_toggle), TRUE);
4081 helper.current_priority = GTK_TOGGLE_BUTTON (high_toggle);
4083 case TNY_HEADER_FLAG_LOW_PRIORITY:
4084 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (low_toggle), TRUE);
4085 helper.current_priority = GTK_TOGGLE_BUTTON (low_toggle);
4088 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (medium_toggle), TRUE);
4089 helper.current_priority = GTK_TOGGLE_BUTTON (medium_toggle);
4093 switch (modest_msg_edit_window_get_format (window)) {
4094 case MODEST_MSG_EDIT_FORMAT_TEXT:
4095 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (text_toggle), TRUE);
4096 helper.current_format = GTK_TOGGLE_BUTTON (text_toggle);
4098 case MODEST_MSG_EDIT_FORMAT_HTML:
4100 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (html_toggle), TRUE);
4101 helper.current_format = GTK_TOGGLE_BUTTON (html_toggle);
4105 /* Signal connects */
4106 g_signal_connect (G_OBJECT (high_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4107 g_signal_connect (G_OBJECT (medium_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4108 g_signal_connect (G_OBJECT (low_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4109 g_signal_connect (G_OBJECT (html_toggle), "toggled", G_CALLBACK (on_format_toggle), &helper);
4110 g_signal_connect (G_OBJECT (text_toggle), "toggled", G_CALLBACK (on_format_toggle), &helper);
4112 /* Save settings if the user clicked on done */
4113 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
4114 TnyHeaderFlags flags;
4115 ModestMsgEditFormat old_format, new_format;
4117 /* Set priority flags */
4118 flags = (TnyHeaderFlags) g_object_get_data (G_OBJECT (helper.current_priority), "priority");
4119 if (priv->priority_flags != flags)
4120 modest_msg_edit_window_set_priority_flags (window, flags);
4122 /* Set edit format */
4123 old_format = modest_msg_edit_window_get_format (window);
4124 new_format = (ModestMsgEditFormat) g_object_get_data (G_OBJECT (helper.current_format), "format");
4125 if (old_format != new_format) {
4126 gint file_format = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (helper.current_format), "file-format"));
4127 modest_msg_edit_window_set_file_format (window, file_format);
4131 gtk_widget_destroy (dialog);
4132 g_slist_free (helper.priority_group);
4136 on_message_settings (GtkAction *action,
4137 ModestMsgEditWindow *window)
4139 modest_msg_edit_window_show_msg_settings_dialog (window);
4143 on_cc_button_toggled (HildonCheckButton *button,
4144 ModestMsgEditWindow *window)
4146 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
4148 modest_msg_edit_window_show_cc (MODEST_MSG_EDIT_WINDOW (window),
4149 hildon_check_button_get_active (button));
4153 on_bcc_button_toggled (HildonCheckButton *button,
4154 ModestMsgEditWindow *window)
4156 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
4158 modest_msg_edit_window_show_bcc (MODEST_MSG_EDIT_WINDOW (window),
4159 hildon_check_button_get_active (button));
4163 setup_menu (ModestMsgEditWindow *self)
4165 ModestMsgEditWindowPrivate *priv = NULL;
4167 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(self));
4169 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
4171 /* Settings menu buttons */
4172 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_editor_checknames"), NULL,
4173 APP_MENU_CALLBACK (modest_ui_actions_on_check_names),
4175 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_undo"), "<Ctrl>z",
4176 APP_MENU_CALLBACK (modest_ui_actions_on_undo),
4177 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_undo));
4179 priv->cc_button = hildon_check_button_new (0);
4180 gtk_button_set_label (GTK_BUTTON (priv->cc_button), _("mcen_me_editor_showcc"));
4181 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->cc_button),
4183 modest_hildon2_window_add_button_to_menu (MODEST_HILDON2_WINDOW (self), GTK_BUTTON (priv->cc_button),
4185 g_signal_connect (G_OBJECT (priv->cc_button), "toggled",
4186 G_CALLBACK (on_cc_button_toggled), (gpointer) self);
4187 priv->bcc_button = hildon_check_button_new (0);
4188 gtk_button_set_label (GTK_BUTTON (priv->bcc_button), _("mcen_me_editor_showbcc"));
4189 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->bcc_button),
4191 modest_hildon2_window_add_button_to_menu (MODEST_HILDON2_WINDOW (self), GTK_BUTTON (priv->bcc_button),
4193 g_signal_connect (G_OBJECT (priv->bcc_button), "toggled",
4194 G_CALLBACK (on_bcc_button_toggled), (gpointer) self);
4196 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_editor_attach_inlineimage"), NULL,
4197 APP_MENU_CALLBACK (modest_ui_actions_on_insert_image),
4198 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_set_style));
4199 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_remove_attachments"), NULL,
4200 APP_MENU_CALLBACK (modest_ui_actions_on_remove_attachments),
4201 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_editor_remove_attachment));
4202 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_message_settings"), NULL,
4203 APP_MENU_CALLBACK (on_message_settings),
4205 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_viewer_find"), "<Ctrl>f",
4206 APP_MENU_CALLBACK (modest_ui_actions_on_toggle_find_in_page),