1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37 #include <tny-vfs-stream.h>
38 #include <tny-camel-mem-stream.h>
39 #include <modest-account-protocol.h>
43 #include <modest-account-mgr.h>
44 #include <modest-account-mgr-helpers.h>
46 #include <widgets/modest-msg-edit-window.h>
47 #include <modest-selector-picker.h>
48 #include <widgets/modest-recpt-editor.h>
49 #include <widgets/modest-attachments-view.h>
51 #include <modest-runtime.h>
53 #include "modest-platform.h"
54 #include "modest-icon-names.h"
55 #include "modest-widget-memory.h"
56 #include "modest-window-priv.h"
57 #include "modest-mail-operation.h"
58 #include "modest-tny-platform-factory.h"
59 #include "modest-tny-msg.h"
60 #include "modest-tny-folder.h"
61 #include "modest-tny-account.h"
62 #include "modest-address-book.h"
63 #include "modest-text-utils.h"
64 #include <tny-simple-list.h>
65 #include <modest-wp-text-view.h>
66 #include <wptextbuffer.h>
67 #include <hildon/hildon-pannable-area.h>
68 #include <hildon/hildon-touch-selector.h>
69 #include <hildon/hildon-picker-dialog.h>
70 #include "modest-msg-edit-window-ui-dimming.h"
72 #include "modest-hildon-includes.h"
73 #ifdef MODEST_HAVE_HILDON0_WIDGETS
74 #include <hildon-widgets/hildon-color-chooser.h>
76 #include "widgets/modest-msg-edit-window-ui.h"
77 #ifdef MODEST_HAVE_HILDON0_WIDGETS
78 #include <libgnomevfs/gnome-vfs-mime-utils.h>
80 #include <libgnomevfs/gnome-vfs-mime.h>
82 #include <modest-utils.h>
83 #include "modest-maemo-utils.h"
84 #include <modest-ui-constants.h>
87 #define DEFAULT_FONT_SIZE 3
88 #define DEFAULT_FONT 2
89 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
90 #define DEFAULT_MAIN_VBOX_SPACING 6
91 #define SUBJECT_MAX_LENGTH 1000
92 #define IMAGE_MAX_WIDTH 560
93 #define DEFAULT_FONT_SCALE 1.5
94 #define ATTACHMENT_BUTTON_WIDTH 118
96 static gboolean is_wp_text_buffer_started = FALSE;
98 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
99 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
100 static void modest_msg_edit_window_finalize (GObject *obj);
102 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
103 static void body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
104 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
106 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
107 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
108 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
109 static void text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
110 GtkTextIter *start, GtkTextIter *end,
112 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
113 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
114 static void subject_field_insert_text (GtkEditable *editable,
116 gint new_text_length,
118 ModestMsgEditWindow *window);
119 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
121 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
123 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
124 ModestRecptEditor *editor);
125 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
126 ModestMsgEditWindow *window);
128 /* ModestWindow methods implementation */
129 static void modest_msg_edit_window_disconnect_signals (ModestWindow *window);
130 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
131 gboolean show_toolbar);
132 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
134 ModestMsgEditWindow *window);
135 static void modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window);
136 static void subject_field_move_cursor (GtkEntry *entry,
137 GtkMovementStep step,
141 static void update_window_title (ModestMsgEditWindow *window);
144 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
145 ModestMsgEditWindow *window);
146 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
147 ModestMsgEditWindow *window);
148 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
150 GtkTextIter *match_start,
151 GtkTextIter *match_end);
153 static void remove_tags (WPTextBuffer *buffer);
155 static void on_account_removed (TnyAccountStore *account_store,
159 static void init_window (ModestMsgEditWindow *obj);
161 gboolean scroll_drag_timeout (gpointer userdata);
162 static void correct_scroll (ModestMsgEditWindow *w);
163 static void correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused);
164 static void text_buffer_end_user_action (GtkTextBuffer *buffer,
165 ModestMsgEditWindow *userdata);
166 static void text_buffer_mark_set (GtkTextBuffer *buffer,
169 ModestMsgEditWindow *userdata);
170 static void on_message_settings (GtkAction *action,
171 ModestMsgEditWindow *window);
172 static void setup_menu (ModestMsgEditWindow *self);
174 static void from_field_changed (HildonPickerButton *button,
175 ModestMsgEditWindow *self);
176 static void font_size_clicked (GtkToolButton *button,
177 ModestMsgEditWindow *window);
178 static void font_face_clicked (GtkToolButton *button,
179 ModestMsgEditWindow *window);
180 static void DEBUG_BUFFER (WPTextBuffer *buffer)
184 g_message ("BEGIN BUFFER OF SIZE %d", gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (buffer)));
186 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
187 while (!gtk_text_iter_is_end (&iter)) {
188 GString *output = g_string_new ("");
189 GSList *toggled_tags;
192 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
193 g_string_append_printf (output, "%d: CLOSED [ ", gtk_text_iter_get_offset (&iter));
194 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
195 GtkTextTag *tag = (GtkTextTag *) node->data;
197 g_object_get (G_OBJECT (tag), "name", &name, NULL);
198 output = g_string_append (output, name);
199 g_string_append (output, " ");
201 output = g_string_append (output, "] OPENED [ ");
202 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
203 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
204 GtkTextTag *tag = (GtkTextTag *) node->data;
206 g_object_get (G_OBJECT (tag), "name", &name, NULL);
207 output = g_string_append (output, name);
208 g_string_append (output, " ");
210 output = g_string_append (output, "]\n");
211 g_message ("%s", output->str);
212 g_string_free (output, TRUE);
213 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
215 g_message ("END BUFFER");
219 static const GtkActionEntry hildon2_msg_edit_action_entries [] = {
220 { "MessageSettings", NULL, N_("mcen_me_message_settings"), NULL, NULL, G_CALLBACK (on_message_settings)},
224 /* static gboolean */
225 /* on_key_pressed (GtkWidget *self, */
226 /* GdkEventKey *event, */
227 /* gpointer user_data); */
229 /* list my signals */
236 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
237 struct _ModestMsgEditWindowPrivate {
239 GtkWidget *header_box;
241 ModestPairList *from_field_protos;
242 GtkWidget *from_field;
243 gchar *last_from_account;
244 gchar *original_account_name;
249 gchar *original_mailbox;
253 GtkWidget *bcc_field;
254 GtkWidget *subject_field;
255 GtkWidget *attachments_view;
256 GtkWidget *priority_icon;
257 GtkWidget *subject_box;
258 GtkWidget *add_attachment_button;
260 GtkWidget *cc_caption;
261 GtkWidget *bcc_caption;
262 gboolean update_caption_visibility;
263 GtkWidget *attachments_caption;
265 GtkTextBuffer *text_buffer;
267 GtkWidget *font_size_toolitem;
268 GtkWidget *font_face_toolitem;
269 GtkWidget *font_color_button;
270 GtkWidget *font_color_toolitem;
271 GSList *font_items_group;
272 GtkTreeModel *faces_model;
273 gint current_face_index;
274 GtkWidget *font_tool_button_label;
275 GtkTreeModel *sizes_model;
276 gint current_size_index;
277 GtkWidget *size_tool_button_label;
279 GtkWidget *find_toolbar;
282 GtkWidget *font_dialog;
285 guint correct_scroll_idle;
286 guint scroll_drag_timeout_id;
290 TnyList *attachments;
295 TnyHeaderFlags priority_flags;
297 gboolean can_undo, can_redo;
298 gulong clipboard_change_handler_id;
299 gulong default_clipboard_change_handler_id;
300 gulong account_removed_handler_id;
301 guint clipboard_owner_idle;
302 gchar *clipboard_text;
311 GtkWidget *cc_button;
312 GtkWidget *bcc_button;
315 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
316 MODEST_TYPE_MSG_EDIT_WINDOW, \
317 ModestMsgEditWindowPrivate))
319 static GtkWindowClass *parent_class = NULL;
321 /* uncomment the following if you have defined any signals */
322 /* static guint signals[LAST_SIGNAL] = {0}; */
325 modest_msg_edit_window_get_type (void)
327 static GType my_type = 0;
329 static const GTypeInfo my_info = {
330 sizeof(ModestMsgEditWindowClass),
331 NULL, /* base init */
332 NULL, /* base finalize */
333 (GClassInitFunc) modest_msg_edit_window_class_init,
334 NULL, /* class finalize */
335 NULL, /* class data */
336 sizeof(ModestMsgEditWindow),
338 (GInstanceInitFunc) modest_msg_edit_window_init,
341 my_type = g_type_register_static (MODEST_TYPE_HILDON2_WINDOW,
342 "ModestMsgEditWindow",
350 save_state (ModestWindow *self)
352 modest_widget_memory_save (modest_runtime_get_conf(),
353 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
358 restore_settings (ModestMsgEditWindow *self)
360 ModestConf *conf = NULL;
362 conf = modest_runtime_get_conf ();
364 /* Dim at start clipboard actions */
365 modest_widget_memory_restore (conf, G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
370 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
372 GObjectClass *gobject_class;
373 ModestWindowClass *modest_window_class;
374 gobject_class = (GObjectClass*) klass;
375 modest_window_class = (ModestWindowClass*) klass;
377 parent_class = g_type_class_peek_parent (klass);
378 gobject_class->finalize = modest_msg_edit_window_finalize;
380 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
381 modest_window_class->save_state_func = save_state;
382 modest_window_class->disconnect_signals_func = modest_msg_edit_window_disconnect_signals;
384 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
388 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
390 ModestMsgEditWindowPrivate *priv;
391 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
393 priv->msg_body = NULL;
394 priv->from_field = NULL;
395 priv->to_field = NULL;
396 priv->cc_field = NULL;
397 priv->bcc_field = NULL;
398 priv->subject_field = NULL;
399 priv->attachments = TNY_LIST (tny_simple_list_new ());
400 priv->images = TNY_LIST (tny_simple_list_new ());
401 priv->images_size = 0;
402 priv->images_count = 0;
405 priv->cc_caption = NULL;
406 priv->bcc_caption = NULL;
407 priv->update_caption_visibility = FALSE;
409 priv->priority_flags = 0;
411 priv->find_toolbar = NULL;
412 priv->last_search = NULL;
414 priv->draft_msg = NULL;
415 priv->outbox_msg = NULL;
416 priv->msg_uid = NULL;
418 priv->can_undo = FALSE;
419 priv->can_redo = FALSE;
420 priv->clipboard_change_handler_id = 0;
421 priv->default_clipboard_change_handler_id = 0;
422 priv->account_removed_handler_id = 0;
423 priv->clipboard_owner_idle = 0;
424 priv->clipboard_text = NULL;
427 priv->scroll_drag_timeout_id = 0;
428 priv->correct_scroll_idle = 0;
429 priv->last_upper = 0.0;
431 priv->font_dialog = NULL;
432 priv->app_menu = NULL;
434 priv->references = NULL;
435 priv->in_reply_to = NULL;
437 if (!is_wp_text_buffer_started) {
438 is_wp_text_buffer_started = TRUE;
439 wp_text_buffer_library_init ();
444 hildon_program_add_window (hildon_program_get_instance(),
448 static gboolean account_is_multimailbox (const gchar *account_name, ModestProtocol **mmb_protocol)
450 gchar *transport_account;
451 gboolean result = FALSE;
454 *mmb_protocol = NULL;
456 transport_account = modest_account_mgr_get_server_account_name (modest_runtime_get_account_mgr (),
458 TNY_ACCOUNT_TYPE_TRANSPORT);
459 if (transport_account) {
461 ModestProtocolRegistry *registry;
463 registry = modest_runtime_get_protocol_registry ();
465 proto = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), transport_account,
466 MODEST_ACCOUNT_PROTO, TRUE);
468 ModestProtocol *protocol =
469 modest_protocol_registry_get_protocol_by_name (registry,
470 MODEST_PROTOCOL_REGISTRY_TRANSPORT_PROTOCOLS,
473 modest_protocol_registry_protocol_type_has_tag
475 modest_protocol_get_type_id (protocol),
476 MODEST_PROTOCOL_REGISTRY_MULTI_MAILBOX_PROVIDER_PROTOCOLS)) {
478 *mmb_protocol = protocol;
489 multimailbox_get_default_mailbox (const gchar *account_name)
491 gchar *transport_account;
492 gchar *result = NULL;
494 transport_account = modest_account_mgr_get_server_account_name (modest_runtime_get_account_mgr (),
496 TNY_ACCOUNT_TYPE_TRANSPORT);
497 if (transport_account) {
499 ModestProtocolRegistry *registry;
501 registry = modest_runtime_get_protocol_registry ();
503 proto = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), transport_account,
504 MODEST_ACCOUNT_PROTO, TRUE);
506 ModestProtocol *protocol =
507 modest_protocol_registry_get_protocol_by_name (registry,
508 MODEST_PROTOCOL_REGISTRY_TRANSPORT_PROTOCOLS,
510 if (MODEST_ACCOUNT_PROTOCOL (protocol)) {
511 ModestPairList *pair_list;
513 pair_list = modest_account_protocol_get_from_list (MODEST_ACCOUNT_PROTOCOL (protocol),
516 ModestPair *pair = (ModestPair *) pair_list->data;
517 result = g_strdup ((const gchar *) pair->first);
518 modest_pair_list_free (pair_list);
529 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
531 static ModestPairList*
532 get_transports (void)
534 GSList *transports = NULL;
536 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
537 GSList *accounts = modest_account_mgr_account_names (account_mgr,
538 TRUE /* only enabled accounts. */);
540 GSList *cursor = accounts;
542 gchar *account_name = cursor->data;
545 gchar *transport_account;
546 gboolean multi_mailbox = FALSE;
547 ModestProtocol *protocol = NULL;
549 if (account_is_multimailbox (account_name, &protocol)) {
551 transport_account = modest_account_mgr_get_server_account_name
552 (modest_runtime_get_account_mgr (),
554 TNY_ACCOUNT_TYPE_TRANSPORT);
555 if (protocol && MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
556 ModestPairList *pair_list;
557 pair_list = modest_account_protocol_get_from_list (MODEST_ACCOUNT_PROTOCOL (protocol),
560 transports = g_slist_concat (transports, pair_list);
561 multi_mailbox = TRUE;
566 if (!multi_mailbox) {
567 gchar *from_string = NULL;
569 from_string = modest_account_mgr_get_from_string (account_mgr,
571 if (from_string && account_name) {
572 gchar *name = account_name;
573 ModestPair *pair = modest_pair_new ((gpointer) name,
574 (gpointer) from_string , TRUE);
575 transports = g_slist_prepend (transports, pair);
580 cursor = cursor->next;
582 g_slist_free (accounts); /* only free the accounts, not the elements,
583 * because they are used in the pairlist */
587 static void window_focus (GtkWindow *window,
591 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
595 scroll_drag_timeout (gpointer userdata)
597 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
598 ModestMsgEditWindowPrivate *priv;
600 /* It could happen that the window was already closed */
601 if (!GTK_WIDGET_VISIBLE (win))
604 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
606 correct_scroll_without_drag_check (win, TRUE);
608 priv->scroll_drag_timeout_id = 0;
614 correct_scroll_without_drag_check_idle (gpointer userdata)
616 ModestMsgEditWindow *w = (ModestMsgEditWindow *) userdata;
617 ModestMsgEditWindowPrivate *priv;
619 GdkRectangle rectangle;
620 gint offset_min, offset_max;
624 /* It could happen that the window was already closed */
625 if (!GTK_WIDGET_VISIBLE (w))
628 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
630 insert = gtk_text_buffer_get_insert (priv->text_buffer);
631 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
633 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
634 offset_min = priv->msg_body->allocation.y + rectangle.y;
635 offset_max = offset_min + rectangle.height;
637 vadj = hildon_pannable_area_get_vadjustment (HILDON_PANNABLE_AREA (priv->pannable));
638 offset_min = MAX (offset_min - 48, 0);
639 offset_max = MIN (offset_max + 48, vadj->upper);
641 gtk_adjustment_clamp_page (vadj, (gdouble) offset_min, (gdouble) offset_max);
643 priv->correct_scroll_idle = 0;
648 correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused)
650 ModestMsgEditWindowPrivate *priv;
652 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
654 if (only_if_focused && !gtk_widget_is_focus (priv->msg_body))
657 if (priv->correct_scroll_idle > 0) {
661 priv->correct_scroll_idle = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
662 (GSourceFunc) correct_scroll_without_drag_check_idle,
668 correct_scroll (ModestMsgEditWindow *w)
670 ModestMsgEditWindowPrivate *priv;
672 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
673 if (gtk_grab_get_current () == priv->msg_body) {
674 if (priv->scroll_drag_timeout_id == 0) {
675 priv->scroll_drag_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
677 (GSourceFunc) scroll_drag_timeout,
684 correct_scroll_without_drag_check (w, TRUE);
688 text_buffer_end_user_action (GtkTextBuffer *buffer,
689 ModestMsgEditWindow *userdata)
692 correct_scroll (userdata);
696 text_buffer_mark_set (GtkTextBuffer *buffer,
699 ModestMsgEditWindow *userdata)
701 gtk_text_buffer_begin_user_action (buffer);
702 gtk_text_buffer_end_user_action (buffer);
706 cut_clipboard_check (GtkTextView *text_view,
709 GtkTextBuffer *buffer;
711 buffer = gtk_text_view_get_buffer (text_view);
712 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
713 g_signal_stop_emission_by_name ((gpointer )text_view, "cut-clipboard");
718 copy_clipboard_check (GtkTextView *text_view,
721 GtkTextBuffer *buffer;
723 buffer = gtk_text_view_get_buffer (text_view);
724 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
725 g_signal_stop_emission_by_name ((gpointer )text_view, "copy-clipboard");
730 attachment_deleted (ModestAttachmentsView *attachments_view,
733 modest_msg_edit_window_remove_attachments (MODEST_MSG_EDIT_WINDOW (user_data),
738 connect_signals (ModestMsgEditWindow *obj)
740 ModestMsgEditWindowPrivate *priv;
742 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
744 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
745 G_CALLBACK (text_buffer_refresh_attributes), obj);
746 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
747 G_CALLBACK (text_buffer_can_undo), obj);
748 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
749 G_CALLBACK (text_buffer_can_redo), obj);
750 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
751 G_CALLBACK (body_changed), obj);
752 g_signal_connect (G_OBJECT (priv->text_buffer), "modified-changed",
753 G_CALLBACK (body_changed), obj);
754 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
755 G_CALLBACK (text_buffer_end_user_action), obj);
756 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
757 G_CALLBACK (text_buffer_mark_set), obj);
758 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
759 G_CALLBACK (text_buffer_apply_tag), obj);
760 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
761 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
762 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
763 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
764 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
765 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
767 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
768 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
769 g_signal_connect (G_OBJECT (priv->from_field), "value-changed",
770 G_CALLBACK (from_field_changed), obj);
772 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
773 G_CALLBACK (msg_body_focus), obj);
774 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
775 G_CALLBACK (msg_body_focus), obj);
776 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
777 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
778 "changed", G_CALLBACK (recpt_field_changed), obj);
779 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
780 "changed", G_CALLBACK (recpt_field_changed), obj);
781 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
782 "changed", G_CALLBACK (recpt_field_changed), obj);
783 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
784 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
785 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
787 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
788 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
790 priv->clipboard_change_handler_id =
791 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
792 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
793 priv->default_clipboard_change_handler_id =
794 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
795 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
797 g_signal_connect (G_OBJECT (priv->msg_body), "cut-clipboard", G_CALLBACK (cut_clipboard_check), NULL);
798 g_signal_connect (G_OBJECT (priv->msg_body), "copy-clipboard", G_CALLBACK (copy_clipboard_check), NULL);
799 g_signal_connect (G_OBJECT (priv->attachments_view), "delete", G_CALLBACK (attachment_deleted), obj);
803 init_wp_text_view_style ()
805 static gboolean initialized = FALSE;
808 gtk_rc_parse_string ("class \"WPTextView\" style \"fremantle-textview\"");
814 init_window (ModestMsgEditWindow *obj)
816 GtkWidget *to_caption, *subject_caption;
817 GtkWidget *main_vbox;
818 GtkWidget *add_attachment_align;
819 ModestMsgEditWindowPrivate *priv;
820 GtkActionGroup *action_group;
821 ModestWindowPrivate *parent_priv;
822 GdkPixbuf *window_icon = NULL;
823 GError *error = NULL;
825 GtkSizeGroup *title_size_group;
826 GtkSizeGroup *value_size_group;
827 GtkWidget *attachment_icon;
828 GtkWidget *window_box;
829 GtkWidget *window_align;
830 #if (GTK_MINOR_VERSION >= 10)
831 GdkAtom deserialize_type;
834 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
835 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
837 parent_priv->ui_manager = gtk_ui_manager_new();
838 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
839 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
841 /* Add common actions */
842 gtk_action_group_add_actions (action_group,
843 modest_msg_edit_action_entries,
844 G_N_ELEMENTS (modest_msg_edit_action_entries),
846 gtk_action_group_add_actions (action_group,
847 hildon2_msg_edit_action_entries,
848 G_N_ELEMENTS (hildon2_msg_edit_action_entries),
850 gtk_action_group_add_toggle_actions (action_group,
851 modest_msg_edit_toggle_action_entries,
852 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
854 gtk_action_group_add_radio_actions (action_group,
855 modest_msg_edit_alignment_radio_action_entries,
856 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
858 G_CALLBACK (modest_ui_actions_on_change_justify),
860 gtk_action_group_add_radio_actions (action_group,
861 modest_msg_edit_priority_action_entries,
862 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
864 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
866 gtk_action_group_add_radio_actions (action_group,
867 modest_msg_edit_file_format_action_entries,
868 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
869 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
870 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
872 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
873 g_object_unref (action_group);
875 /* Load the UI definition */
876 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
879 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
880 g_clear_error (&error);
883 /* Add accelerators */
884 gtk_window_add_accel_group (GTK_WINDOW (obj),
885 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
887 parent_priv->menubar = NULL;
889 title_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
890 value_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
892 /* Note: This ModestPairList* must exist for as long as the picker
893 * that uses it, because the ModestSelectorPicker uses the ID opaquely,
894 * so it can't know how to manage its memory. */
895 priv->from_field = modest_selector_picker_new (MODEST_EDITABLE_SIZE,
896 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
898 modest_maemo_utils_set_hbutton_layout (title_size_group, value_size_group,
899 _("mail_va_from"), priv->from_field);
901 priv->to_field = modest_recpt_editor_new ();
902 priv->cc_field = modest_recpt_editor_new ();
903 priv->bcc_field = modest_recpt_editor_new ();
904 priv->subject_box = gtk_hbox_new (FALSE, MODEST_MARGIN_NONE);
905 priv->priority_icon = gtk_image_new ();
906 gtk_box_pack_start (GTK_BOX (priv->subject_box), priv->priority_icon, FALSE, FALSE, 0);
907 priv->subject_field = hildon_entry_new (MODEST_EDITABLE_SIZE);
908 gtk_entry_set_max_length (GTK_ENTRY (priv->subject_field) ,SUBJECT_MAX_LENGTH);
909 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
910 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
911 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
912 gtk_box_pack_start (GTK_BOX (priv->subject_box), priv->subject_field, TRUE, TRUE, 0);
913 priv->add_attachment_button = hildon_button_new (MODEST_EDITABLE_SIZE, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
914 gtk_widget_set_size_request (priv->add_attachment_button, ATTACHMENT_BUTTON_WIDTH, -1);
915 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
916 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
917 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, HILDON_ICON_SIZE_FINGER);
918 hildon_button_set_image (HILDON_BUTTON (priv->add_attachment_button), attachment_icon);
919 add_attachment_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
920 gtk_alignment_set_padding (GTK_ALIGNMENT (add_attachment_align), 0, 0, MODEST_MARGIN_DEFAULT, 0);
921 gtk_container_add (GTK_CONTAINER (add_attachment_align), priv->add_attachment_button);
922 gtk_box_pack_start (GTK_BOX (priv->subject_box), add_attachment_align, FALSE, FALSE, 0);
923 priv->attachments_view = modest_attachments_view_new (NULL);
924 modest_attachments_view_set_style (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
925 MODEST_ATTACHMENTS_VIEW_STYLE_NO_FOCUS);
927 priv->header_box = gtk_vbox_new (FALSE, 0);
929 to_caption = modest_maemo_utils_create_captioned_with_size_type
930 (title_size_group, value_size_group,
931 _("mail_va_to"), FALSE, priv->to_field,
932 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
933 priv->cc_caption = modest_maemo_utils_create_captioned_with_size_type
934 (title_size_group, value_size_group,
935 _("mail_va_cc"), FALSE, priv->cc_field,
936 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
937 priv->bcc_caption = modest_maemo_utils_create_captioned_with_size_type
938 (title_size_group, value_size_group,
939 _("mail_va_hotfix1"), FALSE, priv->bcc_field,
940 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
941 subject_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
942 _("mail_va_subject"), FALSE, priv->subject_box);
943 priv->attachments_caption = modest_maemo_utils_create_captioned_with_size_type (title_size_group, value_size_group,
944 _("mail_va_attachment"),
946 priv->attachments_view,
947 HILDON_SIZE_AUTO_WIDTH |
948 HILDON_SIZE_AUTO_HEIGHT);
949 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), value_size_group); */
950 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), value_size_group); */
951 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), value_size_group); */
952 g_object_unref (title_size_group);
953 g_object_unref (value_size_group);
955 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->from_field, FALSE, FALSE, 0);
956 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
957 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
958 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
959 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
960 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
961 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
963 init_wp_text_view_style ();
965 priv->msg_body = modest_wp_text_view_new ();
968 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
969 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
970 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
971 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
972 #if (GTK_MINOR_VERSION >= 10)
973 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), NULL);
974 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
976 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
977 deserialize_type, TRUE);
979 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
981 priv->find_toolbar = hildon_find_toolbar_new (NULL);
982 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
984 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
986 priv->pannable = hildon_pannable_area_new ();
988 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
989 window_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
990 gtk_alignment_set_padding (GTK_ALIGNMENT (window_align), 0, 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DEFAULT);
992 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
993 gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 0);
994 gtk_container_add (GTK_CONTAINER (window_align), main_vbox);
996 hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA (priv->pannable), window_align);
997 gtk_widget_show_all (GTK_WIDGET(priv->pannable));
999 window_box = gtk_vbox_new (FALSE, 0);
1000 gtk_container_add (GTK_CONTAINER(obj), window_box);
1002 gtk_box_pack_start (GTK_BOX (window_box), priv->pannable, TRUE, TRUE, 0);
1004 /* Set window icon */
1005 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
1007 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
1008 g_object_unref (window_icon);
1013 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
1015 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1017 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
1018 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
1019 priv->clipboard_change_handler_id))
1020 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
1021 priv->clipboard_change_handler_id);
1022 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
1023 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
1024 priv->default_clipboard_change_handler_id))
1025 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
1026 priv->default_clipboard_change_handler_id);
1028 if (priv->account_removed_handler_id &&
1029 g_signal_handler_is_connected (modest_runtime_get_account_store (),
1030 priv->account_removed_handler_id))
1031 g_signal_handler_disconnect(modest_runtime_get_account_store (),
1032 priv->account_removed_handler_id);
1036 modest_msg_edit_window_finalize (GObject *obj)
1038 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1040 /* Sanity check: shouldn't be needed, the window mgr should
1041 call this function before */
1042 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
1044 if (priv->font_dialog != NULL) {
1045 gtk_dialog_response (GTK_DIALOG (priv->font_dialog), GTK_RESPONSE_NONE);
1048 if (priv->clipboard_text != NULL) {
1049 g_free (priv->clipboard_text);
1050 priv->clipboard_text = NULL;
1053 if (priv->draft_msg != NULL) {
1054 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
1055 if (TNY_IS_HEADER (header)) {
1056 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1057 modest_window_mgr_unregister_header (mgr, header);
1059 g_object_unref (priv->draft_msg);
1060 priv->draft_msg = NULL;
1062 if (priv->outbox_msg != NULL) {
1063 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
1064 if (TNY_IS_HEADER (header)) {
1065 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1066 modest_window_mgr_unregister_header (mgr, header);
1068 g_object_unref (priv->outbox_msg);
1069 priv->outbox_msg = NULL;
1071 if (priv->correct_scroll_idle > 0) {
1072 g_source_remove (priv->correct_scroll_idle);
1073 priv->correct_scroll_idle = 0;
1075 if (priv->scroll_drag_timeout_id > 0) {
1076 g_source_remove (priv->scroll_drag_timeout_id);
1077 priv->scroll_drag_timeout_id = 0;
1079 if (priv->clipboard_owner_idle > 0) {
1080 g_source_remove (priv->clipboard_owner_idle);
1081 priv->clipboard_owner_idle = 0;
1083 if (priv->original_account_name)
1084 g_free (priv->original_account_name);
1085 if (priv->original_mailbox)
1086 g_free (priv->original_mailbox);
1087 g_free (priv->msg_uid);
1088 g_free (priv->last_search);
1089 g_free (priv->references);
1090 g_free (priv->in_reply_to);
1091 g_object_unref (priv->faces_model);
1092 g_object_unref (priv->sizes_model);
1093 g_object_unref (priv->attachments);
1094 g_object_unref (priv->images);
1096 /* This had to stay alive for as long as the picker that used it: */
1097 modest_pair_list_free (priv->from_field_protos);
1099 G_OBJECT_CLASS(parent_class)->finalize (obj);
1103 pixbuf_size_prepared (GdkPixbufLoader *loader,
1106 ModestMsgEditWindow *self)
1108 gint new_height, new_width;
1111 new_height = height;
1115 if (width > IMAGE_MAX_WIDTH) {
1116 new_height = height * IMAGE_MAX_WIDTH / width;
1117 new_width = IMAGE_MAX_WIDTH;
1120 gdk_pixbuf_loader_set_size (loader, new_width, new_height);
1124 pixbuf_from_stream (TnyStream *stream,
1125 const gchar *mime_type,
1126 guint64 *stream_size,
1127 ModestMsgEditWindow *self)
1129 GdkPixbufLoader *loader;
1132 GError *error = NULL;
1136 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1138 if (loader == NULL) {
1143 g_signal_connect (G_OBJECT (loader), "size-prepared", G_CALLBACK (pixbuf_size_prepared), self);
1145 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), TRUE);
1147 tny_stream_reset (TNY_STREAM (stream));
1148 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1149 unsigned char read_buffer[128];
1151 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1153 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, &error)) {
1156 /* Allow some UI responsiveness */
1157 while (gtk_events_pending ())
1158 gtk_main_iteration ();
1160 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), FALSE);
1162 gdk_pixbuf_loader_close (loader, &error);
1165 g_error_free (error);
1166 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1168 g_object_ref (pixbuf);
1169 g_object_unref (loader);
1174 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1175 GdkPixbuf *new_pixbuf;
1177 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1178 gdk_pixbuf_get_width (pixbuf);
1179 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1180 g_object_unref (pixbuf);
1181 pixbuf = new_pixbuf;
1185 *stream_size = size;
1191 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1193 ModestMsgEditWindowPrivate *priv;
1196 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1198 g_object_ref (self);
1199 for (iter = tny_list_create_iterator (attachments);
1200 !tny_iterator_is_done (iter);
1201 tny_iterator_next (iter)) {
1202 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1203 const gchar *cid = tny_mime_part_get_content_id (part);
1204 const gchar *mime_type = tny_mime_part_get_content_type (part);
1205 if ((cid != NULL)&&(mime_type != NULL)) {
1206 guint64 stream_size;
1207 TnyStream *stream = tny_mime_part_get_decoded_stream (part);
1208 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size, self);
1211 g_object_unref (stream);
1213 if (pixbuf != NULL) {
1214 priv->images_count ++;
1215 priv->images_size += stream_size;
1216 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1217 g_object_unref (pixbuf);
1220 g_object_unref (part);
1222 g_object_unref (iter);
1223 g_object_unref (self);
1227 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1229 TnyMimePart *parent = NULL;
1230 const gchar *content_type = NULL;
1231 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1233 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1235 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1236 parent = g_object_ref (msg);
1237 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1238 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1241 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1242 iter = tny_list_create_iterator (parts);
1243 while (!tny_iterator_is_done (iter)) {
1245 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1246 content_type = tny_mime_part_get_content_type (part);
1247 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1251 g_object_unref (part);
1253 tny_iterator_next (iter);
1255 g_object_unref (iter);
1256 g_object_unref (parts);
1259 if (parent != NULL) {
1260 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1263 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1264 iter = tny_list_create_iterator (parts);
1265 while (!tny_iterator_is_done (iter)) {
1267 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1268 content_type = tny_mime_part_get_content_type (part);
1269 if (content_type && g_str_has_prefix (content_type, "image/")) {
1270 tny_list_prepend (priv->images, (GObject *) part);
1272 g_object_unref (part);
1273 tny_iterator_next (iter);
1275 g_object_unref (iter);
1276 g_object_unref (parts);
1277 g_object_unref (parent);
1282 update_next_cid (ModestMsgEditWindow *self, TnyList *attachments)
1285 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1287 for (iter = tny_list_create_iterator (attachments) ;
1288 !tny_iterator_is_done (iter);
1289 tny_iterator_next (iter)) {
1290 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1291 const gchar *cid = tny_mime_part_get_content_id (part);
1293 char *invalid = NULL;
1294 gint int_cid = strtol (cid, &invalid, 10);
1295 if ((invalid != NULL) && (*invalid == '\0') && (int_cid >= priv->next_cid)) {
1296 priv->next_cid = int_cid + 1;
1299 g_object_unref (part);
1301 g_object_unref (iter);
1305 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1308 gchar *to, *cc, *bcc, *subject;
1310 ModestMsgEditWindowPrivate *priv;
1311 ModestWindowPrivate *parent_priv;
1313 TnyHeaderFlags priority_flags;
1314 TnyFolder *msg_folder;
1315 gboolean is_html = FALSE;
1316 gboolean field_view_set;
1318 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1319 g_return_if_fail (TNY_IS_MSG (msg));
1321 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1322 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1324 header = tny_msg_get_header (msg);
1325 to = tny_header_dup_to (header);
1326 cc = tny_header_dup_cc (header);
1327 bcc = tny_header_dup_bcc (header);
1328 subject = tny_header_dup_subject (header);
1330 modest_tny_msg_get_references (TNY_MSG (msg), NULL, &(priv->references), &(priv->in_reply_to));
1331 priority_flags = tny_header_get_priority (header);
1334 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1336 field_view_set = TRUE;
1338 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1339 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1340 gtk_widget_show (priv->cc_caption);
1341 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1342 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1343 gtk_widget_hide (priv->cc_caption);
1344 field_view_set = FALSE;
1346 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->cc_button), field_view_set);
1348 field_view_set = TRUE;
1350 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1351 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1352 gtk_widget_show (priv->bcc_caption);
1353 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1354 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1355 gtk_widget_hide (priv->bcc_caption);
1356 field_view_set = FALSE;
1358 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->bcc_button), field_view_set);
1362 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1363 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1366 update_window_title (self);
1368 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1369 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1371 if ((body == NULL)||(body[0] == '\0')) {
1373 body = modest_text_utils_convert_to_html ("");
1376 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1377 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1380 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1383 /* Add attachments to the view */
1384 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1385 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1386 if (tny_list_get_length (priv->attachments) == 0) {
1387 gtk_widget_hide (priv->attachments_caption);
1389 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1390 gtk_widget_show_all (priv->attachments_caption);
1392 get_related_images (self, msg);
1393 update_next_cid (self, priv->attachments);
1394 update_next_cid (self, priv->images);
1395 replace_with_images (self, priv->images);
1397 if (preserve_is_rich && !is_html) {
1398 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1399 /* Get the default format required from configuration */
1400 } else if (!preserve_is_rich && !modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1401 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1404 /* Set the default focus depending on having already a To: field or not */
1405 if ((!to)||(*to == '\0')) {
1406 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1408 gtk_widget_grab_focus (priv->msg_body);
1411 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1413 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1414 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1416 modest_msg_edit_window_set_modified (self, FALSE);
1418 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1419 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1420 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1421 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1423 if (priv->msg_uid) {
1424 g_free (priv->msg_uid);
1425 priv->msg_uid = NULL;
1428 /* we should set a reference to the incoming message if it is a draft */
1429 msg_folder = tny_msg_get_folder (msg);
1431 if (modest_tny_folder_is_local_folder (msg_folder)) {
1432 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1433 if (type == TNY_FOLDER_TYPE_INVALID)
1434 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1436 if (type == TNY_FOLDER_TYPE_DRAFTS)
1437 priv->draft_msg = g_object_ref(msg);
1438 if (type == TNY_FOLDER_TYPE_OUTBOX)
1439 priv->outbox_msg = g_object_ref(msg);
1440 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1442 g_object_unref (msg_folder);
1453 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1455 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1456 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1457 GtkWidget *placeholder;
1458 GtkWidget *tool_item;
1463 GtkWidget *sizes_menu;
1464 GtkWidget *fonts_menu;
1470 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1471 gtk_toolbar_set_show_arrow (GTK_TOOLBAR (parent_priv->toolbar), FALSE);
1472 gtk_toolbar_set_icon_size (GTK_TOOLBAR (parent_priv->toolbar), HILDON_ICON_SIZE_FINGER);
1473 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1475 /* Font color placeholder */
1476 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1477 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1480 priv->font_color_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1481 priv->font_color_button = hildon_color_button_new ();
1482 gtk_widget_set_size_request (priv->font_color_button, -1, 48);
1483 GTK_WIDGET_UNSET_FLAGS (priv->font_color_toolitem, GTK_CAN_FOCUS);
1484 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1485 gtk_container_add (GTK_CONTAINER (priv->font_color_toolitem), priv->font_color_button);
1486 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1487 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1488 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->font_color_toolitem), insert_index);
1489 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1491 G_CALLBACK (modest_msg_edit_window_color_button_change),
1494 /* Font size and face placeholder */
1495 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1496 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1498 tool_item = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
1499 priv->size_tool_button_label = gtk_label_new (NULL);
1500 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1501 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1502 size_text, "</span>", NULL);
1503 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1504 gtk_misc_set_alignment (GTK_MISC (priv->size_tool_button_label), 1.0, 0.5);
1506 hildon_helper_set_logical_font (priv->size_tool_button_label, "LargeSystemFont");
1507 hbox = gtk_hbox_new (MODEST_MARGIN_DEFAULT, FALSE);
1508 gtk_box_pack_start (GTK_BOX (hbox), priv->size_tool_button_label, TRUE, TRUE, 0);
1509 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1510 gtk_misc_set_alignment (GTK_MISC (arrow), 0.0, 0.5);
1511 gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
1512 gtk_widget_set_sensitive (arrow, FALSE);
1513 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), hbox);
1514 sizes_menu = gtk_menu_new ();
1515 priv->sizes_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
1516 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1519 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1520 gtk_list_store_append (GTK_LIST_STORE (priv->sizes_model), &iter);
1522 gtk_list_store_set (GTK_LIST_STORE (priv->sizes_model), &iter,
1526 if (wp_font_size[size_index] == 12)
1527 priv->current_size_index = size_index;
1531 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (font_size_clicked), window);
1532 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1533 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1534 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1535 priv->font_size_toolitem = tool_item;
1538 tool_item = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
1539 priv->font_tool_button_label = gtk_label_new (NULL);
1540 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1541 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1542 gtk_misc_set_alignment (GTK_MISC (priv->font_tool_button_label), 1.0, 0.5);
1544 hildon_helper_set_logical_font (priv->font_tool_button_label, "LargeSystemFont");
1545 hbox = gtk_hbox_new (MODEST_MARGIN_DEFAULT, FALSE);
1546 gtk_box_pack_start (GTK_BOX (hbox), priv->font_tool_button_label, TRUE, TRUE, 0);
1547 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1548 gtk_misc_set_alignment (GTK_MISC (arrow), 0.0, 0.5);
1549 gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
1550 gtk_widget_set_sensitive (arrow, FALSE);
1551 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), hbox);
1552 fonts_menu = gtk_menu_new ();
1553 priv->faces_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
1554 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1557 gtk_list_store_append (GTK_LIST_STORE (priv->faces_model), &iter);
1559 gtk_list_store_set (GTK_LIST_STORE (priv->faces_model), &iter,
1560 0, wp_get_font_name (font_index),
1563 if (font_index == DEFAULT_FONT)
1564 priv->current_face_index = font_index;
1566 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (font_face_clicked), window);
1567 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1568 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1569 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1570 priv->font_face_toolitem = tool_item;
1572 /* Set expand and homogeneous for remaining items */
1573 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1574 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1575 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1576 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1577 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1578 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1579 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1580 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1581 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1583 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1584 will not show the tool items added to the placeholders) */
1585 gtk_widget_show_all (parent_priv->toolbar);
1587 /* Set the no show all *after* showing all items. We do not
1588 want the toolbar to be shown with a show all because it
1589 could go agains the gconf setting regarding showing or not
1590 the toolbar of the editor window */
1591 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1597 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, const gchar *mailbox, gboolean preserve_is_rich)
1600 ModestWindowPrivate *parent_priv;
1601 ModestMsgEditWindowPrivate *priv;
1602 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1603 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1604 ModestWindowMgr *mgr = NULL;
1606 g_return_val_if_fail (msg, NULL);
1607 g_return_val_if_fail (account_name, NULL);
1609 mgr = modest_runtime_get_window_mgr ();
1611 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1613 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1614 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1616 /* Menubar. Update the state of some toggles */
1617 priv->from_field_protos = get_transports ();
1618 priv->original_mailbox = NULL;
1619 modest_selector_picker_set_pair_list (MODEST_SELECTOR_PICKER (priv->from_field), priv->from_field_protos);
1620 if (mailbox && modest_pair_list_find_by_first_as_string (priv->from_field_protos, mailbox)) {
1621 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) mailbox);
1622 priv->original_mailbox = g_strdup (mailbox);
1623 } else if (account_is_multimailbox (account_name, NULL)) {
1624 /* We set the first mailbox as the active mailbox */
1625 priv->original_mailbox = multimailbox_get_default_mailbox (account_name);
1626 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field),
1627 (gpointer) priv->original_mailbox);
1629 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1631 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1632 hildon_button_set_title (HILDON_BUTTON (priv->from_field),
1634 hildon_button_set_value (HILDON_BUTTON (priv->from_field),
1635 hildon_touch_selector_get_current_text
1636 (HILDON_TOUCH_SELECTOR (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (priv->from_field)))));
1637 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1638 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1641 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1643 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1645 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1646 modest_window_set_active_mailbox (MODEST_WINDOW(obj), priv->original_mailbox);
1648 priv->original_account_name = (account_name) ? g_strdup (account_name) : NULL;
1650 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1651 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1652 /* Add common dimming rules */
1653 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1654 modest_msg_edit_window_toolbar_dimming_entries,
1655 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1656 MODEST_WINDOW (obj));
1657 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_toolitem,
1658 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1659 MODEST_WINDOW (obj));
1660 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1661 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1662 MODEST_WINDOW (obj));
1663 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1664 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1665 MODEST_WINDOW (obj));
1666 /* Insert dimming rules group for this window */
1667 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1668 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1670 /* Setup app menu */
1671 setup_menu (MODEST_MSG_EDIT_WINDOW (obj));
1673 /* Checks the dimming rules */
1674 g_object_unref (toolbar_rules_group);
1675 g_object_unref (clipboard_rules_group);
1676 gtk_widget_hide (priv->priority_icon);
1677 gtk_widget_queue_resize (priv->subject_box);
1678 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1680 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1682 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1683 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1684 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1685 priv->update_caption_visibility = TRUE;
1687 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1689 /* Track account-removed signal, this window should be closed
1690 in the case we're creating a mail associated to the account
1692 priv->account_removed_handler_id =
1693 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1695 G_CALLBACK(on_account_removed),
1698 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (MODEST_MSG_EDIT_WINDOW (obj));
1700 return (ModestWindow*) obj;
1704 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1706 GString **string_buffer = (GString **) user_data;
1708 *string_buffer = g_string_append (*string_buffer, buffer);
1714 * @result: A new string which should be freed with g_free().
1717 get_formatted_data (ModestMsgEditWindow *edit_window)
1719 ModestMsgEditWindowPrivate *priv;
1720 GString *string_buffer = g_string_new ("");
1722 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1724 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1726 modest_text_utils_hyperlinkify (string_buffer);
1728 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1730 return g_string_free (string_buffer, FALSE);
1735 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1738 const gchar *account_name;
1739 ModestMsgEditWindowPrivate *priv;
1740 TnyIterator *att_iter;
1741 const gchar *picker_active_id;
1743 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1745 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1747 picker_active_id = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1748 g_return_val_if_fail (picker_active_id, NULL);
1749 account_name = modest_utils_get_account_name_from_recipient (picker_active_id, NULL);
1751 /* don't free these (except from) */
1752 data = g_slice_new0 (MsgData);
1753 data->from = g_strdup ((gchar *) modest_selector_picker_get_active_display_name (MODEST_SELECTOR_PICKER (priv->from_field)));
1754 data->account_name = g_strdup (account_name);
1755 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1756 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1757 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1758 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1759 data->references = g_strdup (priv->references);
1760 data->in_reply_to = g_strdup (priv->in_reply_to);
1761 if (priv->draft_msg) {
1762 data->draft_msg = g_object_ref (priv->draft_msg);
1763 } else if (priv->outbox_msg) {
1764 data->draft_msg = g_object_ref (priv->outbox_msg);
1766 data->draft_msg = NULL;
1769 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1771 gtk_text_buffer_get_bounds (buf, &b, &e);
1772 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1774 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1775 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1777 data->html_body = NULL;
1779 /* deep-copy the data */
1780 att_iter = tny_list_create_iterator (priv->attachments);
1781 data->attachments = NULL;
1782 while (!tny_iterator_is_done (att_iter)) {
1783 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1784 if (!(TNY_IS_MIME_PART(part))) {
1785 g_warning ("strange data in attachment list");
1786 g_object_unref (part);
1787 tny_iterator_next (att_iter);
1790 data->attachments = g_list_append (data->attachments,
1792 tny_iterator_next (att_iter);
1794 g_object_unref (att_iter);
1796 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1797 att_iter = tny_list_create_iterator (priv->images);
1798 data->images = NULL;
1799 while (!tny_iterator_is_done (att_iter)) {
1800 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1802 if (!(TNY_IS_MIME_PART(part))) {
1803 g_warning ("strange data in attachment list");
1804 g_object_unref (part);
1805 tny_iterator_next (att_iter);
1808 cid = tny_mime_part_get_content_id (part);
1810 gchar *image_tag_id;
1811 GtkTextTag *image_tag;
1813 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1814 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1815 g_free (image_tag_id);
1817 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1819 ((gtk_text_iter_has_tag (&iter, image_tag))||
1820 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1821 data->images = g_list_append (data->images,
1822 g_object_ref (part));
1824 g_object_unref (part);
1825 tny_iterator_next (att_iter);
1827 g_object_unref (att_iter);
1829 data->priority_flags = priv->priority_flags;
1836 unref_gobject (GObject *obj, gpointer data)
1838 if (!G_IS_OBJECT(obj))
1840 g_object_unref (obj);
1844 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1847 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1855 g_free (data->from);
1856 g_free (data->subject);
1857 g_free (data->plain_body);
1858 g_free (data->html_body);
1859 g_free (data->account_name);
1860 g_free (data->references);
1861 g_free (data->in_reply_to);
1863 if (data->draft_msg != NULL) {
1864 g_object_unref (data->draft_msg);
1865 data->draft_msg = NULL;
1868 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1869 g_list_free (data->attachments);
1870 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1871 g_list_free (data->images);
1873 g_slice_free (MsgData, data);
1877 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1879 guint64 *parts_size)
1881 ModestMsgEditWindowPrivate *priv;
1883 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1885 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1887 /* TODO: add images */
1888 *parts_size += priv->images_size;
1889 *parts_count += priv->images_count;
1894 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1897 ModestMsgEditWindowPrivate *priv = NULL;
1898 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1900 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1902 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1904 return MODEST_MSG_EDIT_FORMAT_HTML;
1906 return MODEST_MSG_EDIT_FORMAT_TEXT;
1910 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1911 ModestMsgEditFormat format)
1913 ModestMsgEditWindowPrivate *priv;
1915 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1916 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1919 case MODEST_MSG_EDIT_FORMAT_HTML:
1920 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1922 case MODEST_MSG_EDIT_FORMAT_TEXT:
1923 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1926 g_return_if_reached ();
1930 ModestMsgEditFormatState *
1931 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1933 ModestMsgEditFormatState *format_state = NULL;
1934 ModestMsgEditWindowPrivate *priv;
1935 WPTextBufferFormat *buffer_format;
1937 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1939 buffer_format = g_new0 (WPTextBufferFormat, 1);
1940 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1942 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1944 format_state = g_new0 (ModestMsgEditFormatState, 1);
1945 format_state->bold = buffer_format->bold&0x1;
1946 format_state->italics = buffer_format->italic&0x1;
1947 format_state->bullet = buffer_format->bullet&0x1;
1948 format_state->color = buffer_format->color;
1949 format_state->font_size = buffer_format->font_size;
1950 format_state->font_family = wp_get_font_name (buffer_format->font);
1951 format_state->justification = buffer_format->justification;
1952 g_free (buffer_format);
1954 return format_state;
1959 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1960 const ModestMsgEditFormatState *format_state)
1962 ModestMsgEditWindowPrivate *priv;
1963 WPTextBufferFormat *buffer_format;
1964 WPTextBufferFormat *current_format;
1966 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1967 g_return_if_fail (format_state != NULL);
1969 buffer_format = g_new0 (WPTextBufferFormat, 1);
1970 current_format = g_new0 (WPTextBufferFormat, 1);
1972 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1973 gtk_widget_grab_focus (priv->msg_body);
1974 buffer_format->bold = (format_state->bold != FALSE);
1975 buffer_format->italic = (format_state->italics != FALSE);
1976 buffer_format->color = format_state->color;
1977 buffer_format->font_size = format_state->font_size;
1978 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1979 buffer_format->justification = format_state->justification;
1980 buffer_format->bullet = format_state->bullet;
1982 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1984 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1985 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1986 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1987 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1988 buffer_format->cs.font = (buffer_format->font != current_format->font);
1989 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1990 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1992 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1993 if (buffer_format->cs.bold) {
1994 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1995 GINT_TO_POINTER (buffer_format->bold&0x1));
1997 if (buffer_format->cs.italic) {
1998 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1999 GINT_TO_POINTER (buffer_format->italic&0x1));
2001 if (buffer_format->cs.color) {
2002 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2003 GINT_TO_POINTER (&(buffer_format->color)));
2005 if (buffer_format->cs.font_size) {
2006 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2007 GINT_TO_POINTER (buffer_format->font_size));
2009 if (buffer_format->cs.justification) {
2010 switch (buffer_format->justification) {
2011 case GTK_JUSTIFY_LEFT:
2012 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
2013 GINT_TO_POINTER(TRUE));
2015 case GTK_JUSTIFY_CENTER:
2016 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
2017 GINT_TO_POINTER(TRUE));
2019 case GTK_JUSTIFY_RIGHT:
2020 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
2021 GINT_TO_POINTER(TRUE));
2028 if (buffer_format->cs.font) {
2029 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2030 GINT_TO_POINTER (buffer_format->font));
2032 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
2033 if (buffer_format->cs.bullet) {
2034 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
2035 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
2037 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
2039 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
2041 g_free (buffer_format);
2042 g_free (current_format);
2044 /* Check dimming rules */
2045 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2046 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
2050 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
2052 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2054 ModestWindowPrivate *parent_priv;
2055 ModestMsgEditWindowPrivate *priv;
2057 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2058 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2060 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
2061 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu");
2062 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2063 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
2065 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatPlainTextMenu");
2066 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2067 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
2070 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2072 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2073 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
2075 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2076 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
2078 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
2079 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
2082 switch (buffer_format->justification)
2084 case GTK_JUSTIFY_LEFT:
2085 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2087 case GTK_JUSTIFY_CENTER:
2088 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2090 case GTK_JUSTIFY_RIGHT:
2091 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2098 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
2100 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
2101 G_CALLBACK (modest_msg_edit_window_color_button_change),
2103 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
2104 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
2105 G_CALLBACK (modest_msg_edit_window_color_button_change),
2108 if (priv->current_size_index != buffer_format->font_size) {
2112 path = gtk_tree_path_new_from_indices (buffer_format->font_size, -1);
2113 if (gtk_tree_model_get_iter (priv->sizes_model, &iter, path)) {
2117 priv->current_size_index = buffer_format->font_size;
2119 gtk_tree_model_get (priv->sizes_model, &iter, 0, &size_text, -1);
2120 markup = g_strconcat ("<span font_family='Sans'>",
2121 size_text, "</span>", NULL);
2123 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2127 gtk_tree_path_free (path);
2130 if (priv->current_face_index != buffer_format->font) {
2134 path = gtk_tree_path_new_from_indices (buffer_format->font, -1);
2135 if (gtk_tree_model_get_iter (priv->faces_model, &iter, path)) {
2139 priv->current_face_index = buffer_format->font;
2140 gtk_tree_model_get (priv->faces_model, &iter, 0, &face_name, -1);
2141 markup = g_strconcat ("<span font_family='", face_name, "'>Tt</span>", NULL);
2142 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2149 g_free (buffer_format);
2153 #ifdef MODEST_HILDON_VERSION_0
2155 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2158 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2159 ModestMsgEditWindowPrivate *priv;
2160 GtkWidget *dialog = NULL;
2162 GdkColor *new_color = NULL;
2164 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2165 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2167 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2168 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2169 g_free (buffer_format);
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_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2175 (gpointer) new_color);
2178 gtk_widget_destroy (dialog);
2183 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2186 ModestMsgEditWindowPrivate *priv;
2187 GtkWidget *dialog = NULL;
2189 GdkColor *old_color = NULL;
2190 const GdkColor *new_color = NULL;
2192 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2193 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2195 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2196 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2198 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2199 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2200 if (new_color != NULL)
2201 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2203 gtk_widget_destroy (dialog);
2209 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2212 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2213 ModestMsgEditWindowPrivate *priv;
2214 GtkWidget *dialog = NULL;
2216 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2217 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2219 dialog = hildon_color_chooser_new ();
2220 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2221 g_free (buffer_format);
2223 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2225 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2226 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2229 gtk_widget_destroy (dialog);
2234 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2237 ModestMsgEditWindowPrivate *priv;
2238 GtkWidget *dialog = NULL;
2239 GdkColor *old_color = NULL;
2241 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2242 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2244 dialog = hildon_color_chooser_new ();
2245 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2247 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2249 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2250 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2252 gtk_widget_destroy (dialog);
2255 #endif /*!MODEST_HILDON_VERSION_0*/
2260 create_stream_for_uri (const gchar* uri)
2265 TnyStream *result = NULL;
2267 GnomeVFSHandle *handle = NULL;
2268 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2269 if (test == GNOME_VFS_OK) {
2270 TnyStream *vfssstream = TNY_STREAM (tny_vfs_stream_new (handle));
2271 /* Streams over OBEX (Bluetooth) are not seekable but
2272 * we expect them to be (we might need to read them
2273 * several times). So if this is a Bluetooth URI just
2274 * read the whole file into memory (this is not a fast
2275 * protocol so we can assume that these files are not
2276 * going to be very big) */
2277 if ((g_ascii_strncasecmp (uri, "obex://", 7) == 0)||
2278 (g_ascii_strncasecmp (uri, "upnpav://", 9) == 0)) {
2279 TnyStream *memstream = tny_camel_mem_stream_new ();
2280 tny_stream_write_to_stream (vfssstream, memstream);
2281 g_object_unref (vfssstream);
2284 result = vfssstream;
2292 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2295 ModestMsgEditWindowPrivate *priv;
2296 GtkWidget *dialog = NULL;
2298 GSList *uris = NULL;
2299 GSList *uri_node = NULL;
2301 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2303 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2304 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2305 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2307 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2309 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2310 GTK_WINDOW (dialog), GTK_WINDOW (window));
2312 response = gtk_dialog_run (GTK_DIALOG (dialog));
2314 case GTK_RESPONSE_OK:
2316 gchar *current_folder;
2317 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2318 current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
2319 if (current_folder && current_folder != '\0') {
2321 modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_INSERT_IMAGE_PATH,
2322 current_folder, &err);
2324 g_debug ("Error storing latest used folder: %s", err->message);
2328 g_free (current_folder);
2334 gtk_widget_destroy (dialog);
2336 g_object_ref (window);
2337 /* The operation could take some time so allow the dialog to be closed */
2338 while (gtk_events_pending ())
2339 gtk_main_iteration ();
2341 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2343 GnomeVFSHandle *handle = NULL;
2344 GnomeVFSResult result;
2345 GtkTextIter position;
2346 GtkTextMark *insert_mark;
2348 uri = (const gchar *) uri_node->data;
2349 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2350 if (result == GNOME_VFS_OK) {
2352 GnomeVFSFileInfo *info;
2353 gchar *filename, *basename, *escaped_filename;
2354 TnyMimePart *mime_part;
2356 const gchar *mime_type = NULL;
2357 GnomeVFSURI *vfs_uri;
2358 guint64 stream_size;
2360 gnome_vfs_close (handle);
2361 vfs_uri = gnome_vfs_uri_new (uri);
2363 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2364 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2365 g_free (escaped_filename);
2366 gnome_vfs_uri_unref (vfs_uri);
2367 info = gnome_vfs_file_info_new ();
2369 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2370 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2372 mime_type = gnome_vfs_file_info_get_mime_type (info);
2374 mime_part = tny_platform_factory_new_mime_part
2375 (modest_runtime_get_platform_factory ());
2377 TnyStream *stream = create_stream_for_uri (uri);
2379 if (stream == NULL) {
2381 modest_platform_information_banner (NULL, NULL,
2382 _FM("sfil_ib_opening_not_allowed"));
2384 g_object_unref (mime_part);
2385 gnome_vfs_file_info_unref (info);
2389 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2391 content_id = g_strdup_printf ("%d", priv->next_cid);
2392 tny_mime_part_set_content_id (mime_part, content_id);
2393 g_free (content_id);
2396 basename = g_path_get_basename (filename);
2397 tny_mime_part_set_filename (mime_part, basename);
2400 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size, window);
2402 if (pixbuf != NULL) {
2403 priv->images_size += stream_size;
2404 priv->images_count ++;
2405 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2406 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2407 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position,
2408 tny_mime_part_get_content_id (mime_part), pixbuf);
2409 g_object_unref (pixbuf);
2411 tny_list_prepend (priv->images, (GObject *) mime_part);
2412 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2414 modest_platform_information_banner (NULL, NULL,
2415 _("mail_ib_file_operation_failed"));
2419 g_object_unref (mime_part);
2420 gnome_vfs_file_info_unref (info);
2424 g_object_unref (window);
2428 on_attach_file_response (GtkDialog *dialog,
2432 GSList *uris = NULL;
2434 GnomeVFSFileSize total_size, allowed_size;
2435 ModestMsgEditWindow *window;
2436 ModestMsgEditWindowPrivate *priv;
2441 case GTK_RESPONSE_OK:
2443 gchar *current_folder;
2445 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2446 current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
2447 if (current_folder && current_folder != '\0') {
2449 modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_ATTACH_FILE_PATH,
2450 current_folder, &err);
2452 g_debug ("Error storing latest used folder: %s", err->message);
2456 g_free (current_folder);
2463 window = MODEST_MSG_EDIT_WINDOW (user_data);
2464 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2466 /* allowed size is the maximum size - what's already there */
2467 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2468 &att_num, &att_size);
2469 allowed_size = MODEST_MAX_ATTACHMENT_SIZE - att_size;
2472 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2474 const gchar *uri = (const gchar *) uri_node->data;
2477 modest_msg_edit_window_attach_file_one (window, uri, allowed_size);
2479 if (total_size > allowed_size) {
2480 g_warning ("%s: total size: %u",
2481 __FUNCTION__, (unsigned int)total_size);
2484 allowed_size -= total_size;
2486 g_slist_foreach (uris, (GFunc) g_free, NULL);
2487 g_slist_free (uris);
2489 gtk_widget_destroy (GTK_WIDGET (dialog));
2493 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2495 GtkWidget *dialog = NULL;
2496 ModestMsgEditWindowPrivate *priv;
2499 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(window));
2501 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2503 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2506 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window),
2507 GTK_FILE_CHOOSER_ACTION_OPEN);
2508 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2509 conf_folder = modest_conf_get_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_ATTACH_FILE_PATH, NULL);
2510 if (conf_folder && conf_folder[0] != '\0') {
2511 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), conf_folder);
2514 /* Set the default folder to images folder */
2515 docs_folder = g_build_filename (g_getenv (MODEST_MAEMO_UTILS_MYDOCS_ENV),
2516 ".documents", NULL);
2517 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), docs_folder);
2518 g_free (docs_folder);
2520 g_free (conf_folder);
2521 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2522 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2523 GTK_WINDOW (dialog), GTK_WINDOW (window));
2525 /* Connect to response & show */
2526 g_signal_connect (dialog, "response",
2527 G_CALLBACK (on_attach_file_response), window);
2528 gtk_widget_show (dialog);
2533 modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window,
2535 GnomeVFSFileSize allowed_size)
2538 GnomeVFSHandle *handle = NULL;
2539 ModestMsgEditWindowPrivate *priv;
2540 GnomeVFSResult result;
2541 GnomeVFSFileSize size = 0;
2542 g_return_val_if_fail (window, 0);
2543 g_return_val_if_fail (uri, 0);
2545 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2547 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2548 if (result == GNOME_VFS_OK) {
2549 TnyMimePart *mime_part;
2551 const gchar *mime_type = NULL;
2553 gchar *escaped_filename;
2556 GnomeVFSFileInfo *info;
2557 GnomeVFSURI *vfs_uri;
2559 gnome_vfs_close (handle);
2560 vfs_uri = gnome_vfs_uri_new (uri);
2563 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2564 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2565 g_free (escaped_filename);
2566 gnome_vfs_uri_unref (vfs_uri);
2568 info = gnome_vfs_file_info_new ();
2570 if (gnome_vfs_get_file_info (uri,
2572 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2574 mime_type = gnome_vfs_file_info_get_mime_type (info);
2575 mime_part = tny_platform_factory_new_mime_part
2576 (modest_runtime_get_platform_factory ());
2578 /* try to get the attachment's size; this may fail for weird
2579 * file systems, like obex, upnp... */
2580 if (allowed_size != 0 &&
2581 info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
2583 if (size > allowed_size) {
2584 modest_platform_information_banner (NULL, NULL,
2585 _FM("sfil_ib_opening_not_allowed"));
2590 g_warning ("%s: could not get attachment size", __FUNCTION__);
2592 stream = create_stream_for_uri (uri);
2594 if (stream == NULL) {
2596 modest_platform_information_banner (NULL, NULL, _FM("sfil_ib_opening_not_allowed"));
2598 g_object_unref (mime_part);
2600 gnome_vfs_file_info_unref (info);
2604 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2605 g_object_unref (stream);
2607 content_id = g_strdup_printf ("%d", priv->next_cid);
2608 tny_mime_part_set_content_id (mime_part, content_id);
2609 g_free (content_id);
2612 basename = g_path_get_basename (filename);
2613 tny_mime_part_set_filename (mime_part, basename);
2616 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2617 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2619 info->size == 0, info->size);
2620 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2621 gtk_widget_show_all (priv->attachments_caption);
2622 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2624 g_object_unref (mime_part);
2625 gnome_vfs_file_info_unref (info);
2632 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2635 ModestMsgEditWindowPrivate *priv;
2638 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2639 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2641 if (att_list == NULL) {
2642 att_list = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2643 if (!modest_maemo_utils_select_attachments (GTK_WINDOW (window), att_list, TRUE)) {
2644 g_object_unref (att_list);
2649 g_object_ref (att_list);
2652 if (tny_list_get_length (att_list) == 0) {
2653 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2655 gboolean dialog_response;
2656 gchar *message = NULL;
2657 gchar *filename = NULL;
2659 if (tny_list_get_length (att_list) == 1) {
2661 iter = tny_list_create_iterator (att_list);
2662 part = (TnyMimePart *) tny_iterator_get_current (iter);
2663 g_object_unref (iter);
2664 if (TNY_IS_MSG (part)) {
2665 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2667 filename = tny_header_dup_subject (header);
2668 g_object_unref (header);
2670 if (filename == NULL) {
2671 filename = g_strdup (_("mail_va_no_subject"));
2674 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2676 g_object_unref (part);
2678 filename = g_strdup ("");
2680 message = g_strdup_printf (ngettext("emev_nc_delete_attachment",
2681 "emev_nc_delete_attachments",
2682 tny_list_get_length (att_list)), filename);
2685 dialog_response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
2689 if (dialog_response != GTK_RESPONSE_OK) {
2690 g_object_unref (att_list);
2694 for (iter = tny_list_create_iterator (att_list);
2695 !tny_iterator_is_done (iter);
2696 tny_iterator_next (iter)) {
2697 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2698 const gchar *att_id;
2699 tny_list_remove (priv->attachments, (GObject *) mime_part);
2701 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2703 if (tny_list_get_length (priv->attachments) == 0)
2704 gtk_widget_hide (priv->attachments_caption);
2705 att_id = tny_mime_part_get_content_id (mime_part);
2707 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2709 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2710 g_object_unref (mime_part);
2712 g_object_unref (iter);
2715 g_object_unref (att_list);
2717 /* if the last attachment has been removed, focus the Subject: field */
2718 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2719 gtk_widget_grab_focus (priv->subject_field);
2723 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2726 ModestMsgEditWindowPrivate *priv;
2727 GdkColor *new_color;
2728 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2730 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2731 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2734 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2736 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2738 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2740 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2745 font_size_clicked (GtkToolButton *button,
2746 ModestMsgEditWindow *window)
2748 ModestMsgEditWindowPrivate *priv;
2749 GtkWidget *selector, *dialog;
2751 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2753 selector = hildon_touch_selector_new ();
2754 hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector), priv->sizes_model, TRUE);
2755 hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, priv->current_size_index);
2757 dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
2758 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog), HILDON_TOUCH_SELECTOR (selector));
2759 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_font_size"));
2761 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2765 WPTextBufferFormat format;
2767 new_index = hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (selector), 0);
2769 memset (&format, 0, sizeof (format));
2770 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2772 format.cs.font_size = TRUE;
2773 format.cs.text_position = TRUE;
2774 format.cs.font = TRUE;
2775 format.font_size = new_index;
2776 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2778 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2779 GINT_TO_POINTER (new_index)))
2780 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2782 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2783 size_text = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector));
2784 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
2785 size_text, "</span>", NULL);
2787 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2791 gtk_widget_destroy (dialog);
2793 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2798 font_face_clicked (GtkToolButton *button,
2799 ModestMsgEditWindow *window)
2801 ModestMsgEditWindowPrivate *priv;
2802 GtkWidget *selector, *dialog;
2803 GtkCellRenderer *renderer;
2805 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2807 selector = hildon_touch_selector_new ();
2808 renderer = gtk_cell_renderer_text_new ();
2809 hildon_touch_selector_append_column (HILDON_TOUCH_SELECTOR (selector), priv->faces_model,
2810 renderer, "family", 0, "text", 0, NULL);
2811 hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, priv->current_face_index);
2813 dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
2814 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog), HILDON_TOUCH_SELECTOR (selector));
2815 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_font_face"));
2817 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2818 gint new_font_index;
2822 new_font_index = hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (selector), 0);
2823 path = gtk_tree_path_new_from_indices (new_font_index, -1);
2824 if (gtk_tree_model_get_iter (priv->faces_model, &iter, path)) {
2828 gtk_tree_model_get (priv->faces_model, &iter, 0, &face_name, -1);
2830 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2831 GINT_TO_POINTER(new_font_index)))
2832 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2834 markup = g_strconcat ("<span font_family='", face_name, "'>Tt</span>", NULL);
2835 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2837 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2841 gtk_tree_path_free (path);
2844 gtk_widget_destroy (dialog);
2846 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2851 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2854 ModestMsgEditWindowPrivate *priv = NULL;
2855 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2857 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2858 if (!priv->update_caption_visibility)
2861 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2863 gtk_widget_show (priv->cc_caption);
2865 gtk_widget_hide (priv->cc_caption);
2867 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2871 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2874 ModestMsgEditWindowPrivate *priv = NULL;
2875 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2877 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2878 if (!priv->update_caption_visibility)
2881 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2883 gtk_widget_show (priv->bcc_caption);
2885 gtk_widget_hide (priv->bcc_caption);
2887 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2891 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2892 ModestRecptEditor *editor)
2894 ModestMsgEditWindowPrivate *priv;
2896 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2897 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2899 /* we check for low-mem; in that case, show a warning, and don't allow
2900 * for the addressbook
2902 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2905 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2907 if (editor == NULL) {
2908 GtkWidget *view_focus;
2909 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2911 /* This code should be kept in sync with ModestRecptEditor. The
2912 textview inside the recpt editor is the one that really gets the
2913 focus. As it's inside a scrolled window, and this one inside the
2914 hbox recpt editor inherits from, we'll need to go up in the
2915 hierarchy to know if the text view is part of the recpt editor
2916 or if it's a different text entry */
2918 if (gtk_widget_get_parent (view_focus)) {
2919 GtkWidget *first_parent;
2921 first_parent = gtk_widget_get_parent (view_focus);
2922 if (gtk_widget_get_parent (first_parent) &&
2923 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2924 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2929 editor = MODEST_RECPT_EDITOR (priv->to_field);
2933 modest_address_book_select_addresses (editor);
2938 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2940 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2942 modest_msg_edit_window_open_addressbook (window, NULL);
2946 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2947 gboolean show_toolbar)
2949 ModestWindowPrivate *parent_priv;
2951 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2952 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2954 /* We can not just use the code of
2955 modest_msg_edit_window_setup_toolbar because it has a
2956 mixture of both initialization and creation code. */
2958 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2960 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2964 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2965 TnyHeaderFlags priority_flags)
2967 ModestMsgEditWindowPrivate *priv;
2968 ModestWindowPrivate *parent_priv;
2970 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2972 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2973 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2975 if (priv->priority_flags != priority_flags) {
2976 GtkAction *priority_action = NULL;
2978 priv->priority_flags = priority_flags;
2980 switch (priority_flags) {
2981 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2982 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2983 MODEST_HEADER_ICON_HIGH,
2984 HILDON_ICON_SIZE_SMALL);
2985 gtk_widget_show (priv->priority_icon);
2986 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2987 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2989 case TNY_HEADER_FLAG_LOW_PRIORITY:
2990 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2991 MODEST_HEADER_ICON_LOW,
2992 HILDON_ICON_SIZE_SMALL);
2993 gtk_widget_show (priv->priority_icon);
2994 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2995 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2998 gtk_widget_hide (priv->priority_icon);
2999 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
3000 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
3003 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
3004 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3006 gtk_widget_queue_resize (priv->subject_box);
3010 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
3013 ModestMsgEditWindowPrivate *priv;
3014 ModestWindowPrivate *parent_priv;
3015 gint current_format;
3017 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3019 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3020 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3022 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
3023 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
3025 if (current_format != file_format) {
3026 switch (file_format) {
3027 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
3028 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
3029 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
3031 case MODEST_FILE_FORMAT_PLAIN_TEXT:
3035 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
3036 response = gtk_dialog_run (GTK_DIALOG (dialog));
3037 gtk_widget_destroy (dialog);
3038 if (response == GTK_RESPONSE_OK) {
3039 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
3041 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu"));
3042 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
3047 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3048 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3049 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
3054 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
3057 ModestMsgEditWindowPrivate *priv;
3058 WPTextBufferFormat oldfmt, fmt;
3059 gint old_position = 0;
3063 GdkColor *color = NULL;
3064 gboolean bold, bold_set, italic, italic_set;
3065 gboolean underline, underline_set;
3066 gboolean strikethrough, strikethrough_set;
3067 gboolean position_set;
3068 gboolean font_size_set, font_set, color_set;
3071 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3072 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3074 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
3075 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(),
3076 GTK_WINDOW(dialog), GTK_WINDOW (window));
3078 /* First we get the currently selected font information */
3079 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
3081 switch (oldfmt.text_position) {
3082 case TEXT_POSITION_NORMAL:
3085 case TEXT_POSITION_SUPERSCRIPT:
3093 g_object_set (G_OBJECT (dialog),
3094 "bold", oldfmt.bold != FALSE,
3095 "bold-set", !oldfmt.cs.bold,
3096 "underline", oldfmt.underline != FALSE,
3097 "underline-set", !oldfmt.cs.underline,
3098 "italic", oldfmt.italic != FALSE,
3099 "italic-set", !oldfmt.cs.italic,
3100 "strikethrough", oldfmt.strikethrough != FALSE,
3101 "strikethrough-set", !oldfmt.cs.strikethrough,
3102 "color", &oldfmt.color,
3103 "color-set", !oldfmt.cs.color,
3104 "size", wp_font_size[oldfmt.font_size],
3105 "size-set", !oldfmt.cs.font_size,
3106 "position", old_position,
3107 "position-set", !oldfmt.cs.text_position,
3108 "family", wp_get_font_name (oldfmt.font),
3109 "family-set", !oldfmt.cs.font,
3112 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
3113 GTK_WINDOW (dialog), GTK_WINDOW (window));
3114 gtk_widget_show_all (dialog);
3115 priv->font_dialog = dialog;
3116 response = gtk_dialog_run (GTK_DIALOG (dialog));
3117 priv->font_dialog = NULL;
3118 if (response == GTK_RESPONSE_OK) {
3120 g_object_get( dialog,
3122 "bold-set", &bold_set,
3123 "underline", &underline,
3124 "underline-set", &underline_set,
3126 "italic-set", &italic_set,
3127 "strikethrough", &strikethrough,
3128 "strikethrough-set", &strikethrough_set,
3130 "color-set", &color_set,
3132 "size-set", &font_size_set,
3133 "family", &font_name,
3134 "family-set", &font_set,
3135 "position", &position,
3136 "position-set", &position_set,
3141 if (response == GTK_RESPONSE_OK) {
3142 memset(&fmt, 0, sizeof(fmt));
3148 fmt.italic = italic;
3149 fmt.cs.italic = TRUE;
3151 if (underline_set) {
3152 fmt.underline = underline;
3153 fmt.cs.underline = TRUE;
3155 if (strikethrough_set) {
3156 fmt.strikethrough = strikethrough;
3157 fmt.cs.strikethrough = TRUE;
3162 ? TEXT_POSITION_NORMAL
3163 : ( ( position == 1 )
3164 ? TEXT_POSITION_SUPERSCRIPT
3165 : TEXT_POSITION_SUBSCRIPT );
3166 fmt.cs.text_position = TRUE;
3167 fmt.font_size = oldfmt.font_size;
3171 fmt.cs.color = TRUE;
3174 fmt.font = wp_get_font_index(font_name,
3179 if (font_size_set) {
3180 fmt.cs.font_size = TRUE;
3181 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
3183 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
3184 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
3186 gtk_widget_destroy (dialog);
3188 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
3192 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
3194 ModestMsgEditWindowPrivate *priv;
3196 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3197 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3199 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
3201 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3202 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3206 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
3208 ModestMsgEditWindowPrivate *priv;
3210 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3211 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3213 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
3215 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3216 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3221 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
3223 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3225 priv->can_undo = can_undo;
3229 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
3231 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3233 priv->can_redo = can_redo;
3237 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
3239 ModestMsgEditWindowPrivate *priv;
3240 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3241 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3243 return priv->can_undo;
3247 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
3249 ModestMsgEditWindowPrivate *priv;
3250 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3251 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3253 return priv->can_redo;
3258 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
3261 GtkTextIter match_start, match_end;
3263 if (image_id == NULL)
3266 gtk_text_buffer_get_start_iter (buffer, &iter);
3268 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
3269 GSList *tags = gtk_text_iter_get_tags (&match_start);
3271 for (node = tags; node != NULL; node = g_slist_next (node)) {
3272 GtkTextTag *tag = (GtkTextTag *) node->data;
3273 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
3274 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
3275 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
3277 offset = gtk_text_iter_get_offset (&match_start);
3278 gtk_text_buffer_delete (buffer, &match_start, &match_end);
3279 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
3283 gtk_text_iter_forward_char (&iter);
3288 message_is_empty (ModestMsgEditWindow *window)
3290 ModestMsgEditWindowPrivate *priv = NULL;
3292 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3293 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3295 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
3296 * so we can ignore markup.
3298 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
3301 count = gtk_text_buffer_get_char_count (buf);
3307 msg_body_focus (GtkWidget *focus,
3308 GdkEventFocus *event,
3312 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3313 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3314 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3319 recpt_field_changed (GtkTextBuffer *buffer,
3320 ModestMsgEditWindow *editor)
3322 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3323 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3327 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3329 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3330 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3334 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3337 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3338 GtkTextBuffer *buffer;
3340 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3341 gtk_text_buffer_set_modified (buffer, modified);
3342 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3343 gtk_text_buffer_set_modified (buffer, modified);
3344 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3345 gtk_text_buffer_set_modified (buffer, modified);
3346 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3350 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3352 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3353 const char *account_name;
3354 GtkTextBuffer *buffer;
3356 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3357 if (gtk_text_buffer_get_modified (buffer))
3359 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3360 if (gtk_text_buffer_get_modified (buffer))
3362 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3363 if (gtk_text_buffer_get_modified (buffer))
3365 if (gtk_text_buffer_get_modified (priv->text_buffer))
3368 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3369 if (priv->original_mailbox) {
3370 if (!account_name || strcmp (account_name, priv->original_mailbox))
3372 } else if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3383 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3385 ModestMsgEditWindowPrivate *priv = NULL;
3387 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3388 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3390 /* check if there's no recipient added */
3391 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3392 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3393 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3394 /* no recipient contents, then select contacts */
3395 modest_msg_edit_window_open_addressbook (window, NULL);
3399 g_object_ref (window);
3400 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3401 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3402 g_object_unref (window);
3405 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3406 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3407 g_object_unref (window);
3410 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3411 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3412 g_object_unref (window);
3416 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3417 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3418 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3419 g_object_unref (window);
3426 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3427 ModestMsgEditWindow *window)
3429 modest_msg_edit_window_offer_attach_file (window);
3433 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3435 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3437 return priv->clipboard_text;
3441 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3443 ModestMsgEditWindow *window)
3445 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3446 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3449 /* It could happen that the window was already closed */
3450 if (!GTK_WIDGET_VISIBLE (window))
3453 g_object_ref (window);
3454 text = gtk_clipboard_wait_for_text (selection_clipboard);
3456 if (priv->clipboard_text != NULL) {
3457 g_free (priv->clipboard_text);
3459 priv->clipboard_text = text;
3461 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3463 g_object_unref (window);
3466 static gboolean clipboard_owner_change_idle (gpointer userdata)
3468 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
3469 ModestMsgEditWindowPrivate *priv;
3471 gdk_threads_enter ();
3472 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3473 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3475 priv->clipboard_owner_idle = 0;
3476 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, window);
3477 gdk_threads_leave ();
3483 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window)
3485 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3486 if (priv->clipboard_owner_idle == 0) {
3487 priv->clipboard_owner_idle = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
3488 clipboard_owner_change_idle,
3489 g_object_ref (window),
3495 subject_field_move_cursor (GtkEntry *entry,
3496 GtkMovementStep step,
3501 /* It could happen that the window was already closed */
3502 if (!GTK_WIDGET_VISIBLE (window))
3505 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3509 update_window_title (ModestMsgEditWindow *window)
3511 ModestMsgEditWindowPrivate *priv = NULL;
3512 const gchar *subject;
3514 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3515 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3516 if (subject == NULL || subject[0] == '\0')
3517 subject = _("mail_va_new_email");
3519 gtk_window_set_title (GTK_WINDOW (window), subject);
3524 subject_field_changed (GtkEditable *editable,
3525 ModestMsgEditWindow *window)
3527 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3528 update_window_title (window);
3529 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3530 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3531 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3535 subject_field_insert_text (GtkEditable *editable,
3537 gint new_text_length,
3539 ModestMsgEditWindow *window)
3541 GString *result = g_string_new ("");
3543 gint result_len = 0;
3544 const gchar *entry_text = NULL;
3547 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3548 old_length = g_utf8_strlen (entry_text, -1);
3550 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3551 gunichar c = g_utf8_get_char_validated (current, 8);
3552 /* Invalid unichar, stop */
3558 result = g_string_append_unichar (result, c);
3562 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3563 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3566 /* Prevent endless recursion */
3567 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3568 g_signal_emit_by_name (editable, "insert-text",
3569 (gpointer) result->str, (gpointer) result->len,
3570 (gpointer) position, (gpointer) window);
3571 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3575 if (result_len + old_length > 1000) {
3576 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3577 _CS("ckdg_ib_maximum_characters_reached"));
3579 g_string_free (result, TRUE);
3583 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3586 ModestMsgEditWindowPrivate *priv = NULL;
3588 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3589 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3591 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3594 gtk_widget_show_all (priv->find_toolbar);
3595 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3597 gtk_widget_hide_all (priv->find_toolbar);
3598 gtk_widget_grab_focus (priv->msg_body);
3603 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3605 GtkTextIter *match_start,
3606 GtkTextIter *match_end)
3608 GtkTextIter end_iter;
3609 gchar *str_casefold;
3612 gchar *range_casefold;
3615 gboolean result = FALSE;
3622 gtk_text_iter_forward_to_end (&end_iter);
3624 str_casefold = g_utf8_casefold (str, -1);
3625 str_chars_n = strlen (str);
3627 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3628 range_casefold = g_utf8_casefold (range_text, -1);
3629 range_chars_n = strlen (range_casefold);
3631 if (range_chars_n < str_chars_n) {
3632 g_free (str_casefold);
3633 g_free (range_text);
3634 g_free (range_casefold);
3638 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3639 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3640 if (!g_utf8_collate (range_subtext, str_casefold)) {
3641 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3643 if (!gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3644 match_start, match_end, NULL)) {
3645 g_warning ("Matched string with collate, but not matched in model");
3647 g_free (found_text);
3649 g_free (range_subtext);
3653 g_free (str_casefold);
3654 g_free (range_text);
3655 g_free (range_casefold);
3662 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3663 ModestMsgEditWindow *window)
3665 gchar *current_search = NULL;
3666 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3668 GtkTextIter selection_start, selection_end;
3669 GtkTextIter match_start, match_end;
3670 gboolean continue_search = FALSE;
3672 if (message_is_empty (window)) {
3673 g_free (priv->last_search);
3674 priv->last_search = NULL;
3675 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3679 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3680 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3681 g_free (current_search);
3682 g_free (priv->last_search);
3683 priv->last_search = NULL;
3684 /* Information banner about empty search */
3685 hildon_banner_show_information (NULL, NULL, _CS("ecdg_ib_find_rep_enter_text"));
3689 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3690 continue_search = TRUE;
3692 g_free (priv->last_search);
3693 priv->last_search = g_strdup (current_search);
3696 if (continue_search) {
3697 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3698 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3699 &match_start, &match_end);
3701 hildon_banner_show_information (NULL, NULL, _HL("ckct_ib_find_search_complete"));
3703 GtkTextIter buffer_start;
3704 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3705 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3706 &match_start, &match_end);
3708 hildon_banner_show_information (NULL, NULL, _HL("ckct_ib_find_no_matches"));
3711 /* Mark as selected the string found in search */
3713 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3714 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3715 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3717 g_free (priv->last_search);
3718 priv->last_search = NULL;
3720 g_free (current_search);
3724 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3726 ModestMsgEditWindowPrivate *priv;
3728 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3733 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3736 ModestMsgEditWindowPrivate *priv;
3738 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3743 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3744 ModestMsgEditWindow *window)
3746 modest_msg_edit_window_toggle_find_toolbar (window, FALSE);
3750 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3753 ModestMsgEditWindowPrivate *priv;
3754 TnyHeader *header = NULL;
3756 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3757 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3759 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3761 if (priv->draft_msg != NULL) {
3762 g_object_unref (priv->draft_msg);
3765 if (draft != NULL) {
3766 g_object_ref (draft);
3767 header = tny_msg_get_header (draft);
3768 if (priv->msg_uid) {
3769 g_free (priv->msg_uid);
3770 priv->msg_uid = NULL;
3772 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3775 priv->draft_msg = draft;
3779 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3780 GtkTextIter *start, GtkTextIter *end,
3783 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3784 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3787 if (tag == NULL) return;
3788 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3789 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3790 replace_with_images (window, priv->images);
3795 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3798 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3800 g_return_if_fail (TNY_IS_MIME_PART (part));
3801 tny_list_prepend (priv->attachments, (GObject *) part);
3802 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3803 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3804 gtk_widget_show_all (priv->attachments_caption);
3805 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3809 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3811 ModestMsgEditWindowPrivate *priv;
3813 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3814 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3816 return priv->msg_uid;
3820 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3821 ModestMsgEditWindowWidgetType widget_type)
3823 ModestMsgEditWindowPrivate *priv;
3825 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3826 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3828 switch (widget_type) {
3829 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3830 return priv->msg_body;
3832 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3833 return priv->to_field;
3835 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3836 return priv->cc_field;
3838 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3839 return priv->bcc_field;
3841 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3842 return priv->subject_field;
3844 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3845 return priv->attachments_view;
3853 remove_tags (WPTextBuffer *buffer)
3855 GtkTextIter start, end;
3857 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3858 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3860 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3864 on_account_removed (TnyAccountStore *account_store,
3865 TnyAccount *account,
3868 /* Do nothing if it's a store account, because we use the
3869 transport to send the messages */
3870 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3871 const gchar *parent_acc = NULL;
3872 const gchar *our_acc = NULL;
3874 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3875 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3876 /* Close this window if I'm showing a message of the removed account */
3877 if (strcmp (parent_acc, our_acc) == 0)
3878 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3883 from_field_changed (HildonPickerButton *button,
3884 ModestMsgEditWindow *self)
3886 ModestMsgEditWindowPrivate *priv;
3887 gboolean has_old_signature, has_new_signature;
3889 GtkTextIter match_start, match_end;
3890 ModestAccountMgr *mgr;
3892 gchar *full_signature;
3894 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
3896 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
3897 mgr = modest_runtime_get_account_mgr ();
3898 signature = modest_account_mgr_get_signature (mgr, priv->last_from_account, &has_old_signature);
3899 if (has_old_signature) {
3900 full_signature = g_strconcat ("\n--\n", signature, NULL);
3901 if (gtk_text_iter_forward_search (&iter, full_signature, 0, &match_start, &match_end, NULL)) {
3902 gtk_text_buffer_delete (priv->text_buffer, &match_start, &match_end);
3904 } else if (gtk_text_iter_forward_search (&iter, _("mcen_ia_editor_original_message"), 0,
3905 &match_start, &match_end, NULL)) {
3908 g_free (full_signature);
3912 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3913 signature = modest_account_mgr_get_signature (mgr, priv->last_from_account, &has_new_signature);
3914 if (has_new_signature) {
3915 full_signature = g_strconcat ("\n--\n", signature, NULL);
3916 gtk_text_buffer_insert (priv->text_buffer, &iter, full_signature, -1);
3917 g_free (full_signature);
3922 typedef struct _MessageSettingsHelper {
3923 ModestMsgEditWindow *window;
3924 GSList *priority_group;
3925 GSList *format_group;
3926 GtkToggleButton *current_priority;
3927 GtkToggleButton *current_format;
3928 } MessageSettingsHelper;
3931 on_priority_toggle (GtkToggleButton *button,
3932 MessageSettingsHelper *helper)
3935 ModestMsgEditWindowPrivate *priv;
3937 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (helper->window);
3938 if (gtk_toggle_button_get_active (button)) {
3940 for (node = helper->priority_group; node != NULL; node = g_slist_next (node)) {
3941 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3942 if ((node_button != button) &&
3943 gtk_toggle_button_get_active (node_button)) {
3944 gtk_toggle_button_set_active (node_button, FALSE);
3947 helper->current_priority = button;
3949 gboolean found = FALSE;
3950 /* If no one is active, activate it again */
3951 for (node = helper->priority_group; node != NULL; node = g_slist_next (node)) {
3952 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3953 if (gtk_toggle_button_get_active (node_button)) {
3959 gtk_toggle_button_set_active (button, TRUE);
3965 on_format_toggle (GtkToggleButton *button,
3966 MessageSettingsHelper *helper)
3969 ModestMsgEditWindowPrivate *priv;
3971 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (helper->window);
3972 if (gtk_toggle_button_get_active (button)) {
3974 for (node = helper->format_group; node != NULL; node = g_slist_next (node)) {
3975 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3976 if ((node_button != button) &&
3977 gtk_toggle_button_get_active (node_button)) {
3978 gtk_toggle_button_set_active (node_button, FALSE);
3981 helper->current_format = button;
3983 gboolean found = FALSE;
3984 /* If no one is active, activate it again */
3985 for (node = helper->format_group; node != NULL; node = g_slist_next (node)) {
3986 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3987 if (gtk_toggle_button_get_active (node_button)) {
3993 gtk_toggle_button_set_active (button, TRUE);
4000 modest_msg_edit_window_show_msg_settings_dialog (ModestMsgEditWindow *window)
4005 GtkWidget *priority_hbox;
4006 GtkWidget *high_toggle, *medium_toggle, *low_toggle;
4007 GtkWidget *captioned;
4008 GtkSizeGroup *title_sizegroup, *value_sizegroup;
4009 GtkWidget *format_hbox;
4010 GtkWidget *html_toggle, *text_toggle;
4011 ModestMsgEditWindowPrivate *priv;
4012 MessageSettingsHelper helper = {0,};
4014 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4015 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
4016 helper.window = window;
4017 helper.priority_group = NULL;
4018 helper.format_group = NULL;
4020 title_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4021 value_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4023 dialog = gtk_dialog_new_with_buttons (_("mcen_me_message_settings"), NULL,
4024 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
4025 _HL("wdgt_bd_done"), GTK_RESPONSE_ACCEPT, NULL);
4026 vbox = gtk_vbox_new (FALSE, 0);
4027 align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
4028 gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE, 0);
4029 gtk_container_add (GTK_CONTAINER (align), vbox);
4030 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), align);
4031 gtk_widget_show (align);
4032 gtk_widget_show (vbox);
4034 /* Priority toggles */
4035 priority_hbox = gtk_hbox_new (TRUE, 0);
4036 high_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4037 gtk_button_set_label (GTK_BUTTON (high_toggle), _("mcen_me_editor_priority_high"));
4038 helper.priority_group = g_slist_prepend (helper.priority_group, high_toggle);
4039 g_object_set_data (G_OBJECT (high_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_HIGH_PRIORITY));
4040 medium_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4041 gtk_button_set_label (GTK_BUTTON (medium_toggle), _("mcen_me_editor_priority_normal"));
4042 helper.priority_group = g_slist_prepend (helper.priority_group, medium_toggle);
4043 g_object_set_data (G_OBJECT (medium_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_NORMAL_PRIORITY));
4044 low_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4045 gtk_button_set_label (GTK_BUTTON (low_toggle), _("mcen_me_editor_priority_low"));
4046 helper.priority_group = g_slist_prepend (helper.priority_group, low_toggle);
4047 g_object_set_data (G_OBJECT (low_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_LOW_PRIORITY));
4048 gtk_box_pack_start (GTK_BOX (priority_hbox), low_toggle, TRUE, TRUE, 0);
4049 gtk_box_pack_start (GTK_BOX (priority_hbox), medium_toggle, TRUE, TRUE, 0);
4050 gtk_box_pack_start (GTK_BOX (priority_hbox), high_toggle, TRUE, TRUE, 0);
4051 gtk_widget_show_all (priority_hbox);
4052 captioned = modest_maemo_utils_create_captioned (title_sizegroup, value_sizegroup,
4053 _("mcen_me_editor_message_priority"), FALSE, priority_hbox);
4054 gtk_widget_show (captioned);
4055 gtk_box_pack_start (GTK_BOX (vbox), captioned, FALSE, FALSE, 0);
4057 /* format toggles */
4058 format_hbox = gtk_hbox_new (TRUE, 0);
4059 html_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4060 gtk_button_set_label (GTK_BUTTON (html_toggle), _("mcen_me_editor_formatted_text"));
4061 helper.format_group = g_slist_prepend (helper.format_group, html_toggle);
4062 g_object_set_data (G_OBJECT (html_toggle), "format", GINT_TO_POINTER (MODEST_MSG_EDIT_FORMAT_HTML));
4063 g_object_set_data (G_OBJECT (html_toggle), "file-format", GINT_TO_POINTER (MODEST_FILE_FORMAT_FORMATTED_TEXT));
4064 text_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4065 gtk_button_set_label (GTK_BUTTON (text_toggle), _("mcen_me_editor_plain_text"));
4066 helper.format_group = g_slist_prepend (helper.format_group, text_toggle);
4067 g_object_set_data (G_OBJECT (text_toggle), "format", GINT_TO_POINTER (MODEST_MSG_EDIT_FORMAT_TEXT));
4068 g_object_set_data (G_OBJECT (text_toggle), "file-format", GINT_TO_POINTER (MODEST_FILE_FORMAT_PLAIN_TEXT));
4069 gtk_box_pack_start (GTK_BOX (format_hbox), html_toggle, TRUE, TRUE, 0);
4070 gtk_box_pack_start (GTK_BOX (format_hbox), text_toggle, TRUE, TRUE, 0);
4071 gtk_widget_show_all (format_hbox);
4072 gtk_widget_show (format_hbox);
4073 gtk_box_pack_start (GTK_BOX (vbox), format_hbox, FALSE, FALSE, 0);
4076 g_object_unref (title_sizegroup);
4077 g_object_unref (value_sizegroup);
4079 /* Set current values */
4080 switch (priv->priority_flags) {
4081 case TNY_HEADER_FLAG_HIGH_PRIORITY:
4082 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (high_toggle), TRUE);
4083 helper.current_priority = GTK_TOGGLE_BUTTON (high_toggle);
4085 case TNY_HEADER_FLAG_LOW_PRIORITY:
4086 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (low_toggle), TRUE);
4087 helper.current_priority = GTK_TOGGLE_BUTTON (low_toggle);
4090 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (medium_toggle), TRUE);
4091 helper.current_priority = GTK_TOGGLE_BUTTON (medium_toggle);
4095 switch (modest_msg_edit_window_get_format (window)) {
4096 case MODEST_MSG_EDIT_FORMAT_TEXT:
4097 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (text_toggle), TRUE);
4098 helper.current_format = GTK_TOGGLE_BUTTON (text_toggle);
4100 case MODEST_MSG_EDIT_FORMAT_HTML:
4102 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (html_toggle), TRUE);
4103 helper.current_format = GTK_TOGGLE_BUTTON (html_toggle);
4107 /* Signal connects */
4108 g_signal_connect (G_OBJECT (high_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4109 g_signal_connect (G_OBJECT (medium_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4110 g_signal_connect (G_OBJECT (low_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4111 g_signal_connect (G_OBJECT (html_toggle), "toggled", G_CALLBACK (on_format_toggle), &helper);
4112 g_signal_connect (G_OBJECT (text_toggle), "toggled", G_CALLBACK (on_format_toggle), &helper);
4114 /* Save settings if the user clicked on done */
4115 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
4116 TnyHeaderFlags flags;
4117 ModestMsgEditFormat old_format, new_format;
4119 /* Set priority flags */
4120 flags = (TnyHeaderFlags) g_object_get_data (G_OBJECT (helper.current_priority), "priority");
4121 if (priv->priority_flags != flags)
4122 modest_msg_edit_window_set_priority_flags (window, flags);
4124 /* Set edit format */
4125 old_format = modest_msg_edit_window_get_format (window);
4126 new_format = (ModestMsgEditFormat) g_object_get_data (G_OBJECT (helper.current_format), "format");
4127 if (old_format != new_format) {
4128 gint file_format = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (helper.current_format), "file-format"));
4129 modest_msg_edit_window_set_file_format (window, file_format);
4133 gtk_widget_destroy (dialog);
4134 g_slist_free (helper.priority_group);
4138 on_message_settings (GtkAction *action,
4139 ModestMsgEditWindow *window)
4141 modest_msg_edit_window_show_msg_settings_dialog (window);
4145 on_cc_button_toggled (HildonCheckButton *button,
4146 ModestMsgEditWindow *window)
4148 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
4150 modest_msg_edit_window_show_cc (MODEST_MSG_EDIT_WINDOW (window),
4151 hildon_check_button_get_active (button));
4155 on_bcc_button_toggled (HildonCheckButton *button,
4156 ModestMsgEditWindow *window)
4158 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
4160 modest_msg_edit_window_show_bcc (MODEST_MSG_EDIT_WINDOW (window),
4161 hildon_check_button_get_active (button));
4165 setup_menu (ModestMsgEditWindow *self)
4167 ModestMsgEditWindowPrivate *priv = NULL;
4169 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(self));
4171 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
4173 /* Settings menu buttons */
4174 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_editor_checknames"), NULL,
4175 APP_MENU_CALLBACK (modest_ui_actions_on_check_names),
4177 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_undo"), "<Ctrl>z",
4178 APP_MENU_CALLBACK (modest_ui_actions_on_undo),
4179 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_undo));
4181 priv->cc_button = hildon_check_button_new (0);
4182 gtk_button_set_label (GTK_BUTTON (priv->cc_button), _("mcen_me_editor_showcc"));
4183 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->cc_button),
4185 modest_hildon2_window_add_button_to_menu (MODEST_HILDON2_WINDOW (self), GTK_BUTTON (priv->cc_button),
4187 g_signal_connect (G_OBJECT (priv->cc_button), "toggled",
4188 G_CALLBACK (on_cc_button_toggled), (gpointer) self);
4189 priv->bcc_button = hildon_check_button_new (0);
4190 gtk_button_set_label (GTK_BUTTON (priv->bcc_button), _("mcen_me_editor_showbcc"));
4191 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->bcc_button),
4193 modest_hildon2_window_add_button_to_menu (MODEST_HILDON2_WINDOW (self), GTK_BUTTON (priv->bcc_button),
4195 g_signal_connect (G_OBJECT (priv->bcc_button), "toggled",
4196 G_CALLBACK (on_bcc_button_toggled), (gpointer) self);
4198 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_editor_attach_inlineimage"), NULL,
4199 APP_MENU_CALLBACK (modest_ui_actions_on_insert_image),
4200 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_set_style));
4201 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_remove_attachments"), NULL,
4202 APP_MENU_CALLBACK (modest_ui_actions_on_remove_attachments),
4203 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_editor_remove_attachment));
4204 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_message_settings"), NULL,
4205 APP_MENU_CALLBACK (on_message_settings),
4207 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_viewer_find"), "<Ctrl>f",
4208 APP_MENU_CALLBACK (modest_ui_actions_on_toggle_find_in_page),