1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37 #include <tny-vfs-stream.h>
38 #include <tny-camel-mem-stream.h>
39 #include <modest-account-protocol.h>
43 #include <modest-account-mgr.h>
44 #include <modest-account-mgr-helpers.h>
46 #include <widgets/modest-msg-edit-window.h>
47 #include <modest-selector-picker.h>
48 #include <widgets/modest-recpt-editor.h>
49 #include <widgets/modest-attachments-view.h>
51 #include <modest-runtime.h>
53 #include "modest-platform.h"
54 #include "modest-icon-names.h"
55 #include "modest-widget-memory.h"
56 #include "modest-window-priv.h"
57 #include "modest-mail-operation.h"
58 #include "modest-tny-platform-factory.h"
59 #include "modest-tny-msg.h"
60 #include "modest-tny-folder.h"
61 #include "modest-tny-account.h"
62 #include "modest-address-book.h"
63 #include "modest-text-utils.h"
64 #include <tny-simple-list.h>
65 #include <modest-wp-text-view.h>
66 #include <wptextbuffer.h>
67 #include <hildon/hildon-pannable-area.h>
68 #include <hildon/hildon-touch-selector.h>
69 #include <hildon/hildon-picker-dialog.h>
70 #include "modest-msg-edit-window-ui-dimming.h"
72 #include "modest-hildon-includes.h"
73 #ifdef MODEST_HAVE_HILDON0_WIDGETS
74 #include <hildon-widgets/hildon-color-chooser.h>
76 #include "widgets/modest-msg-edit-window-ui.h"
77 #ifdef MODEST_HAVE_HILDON0_WIDGETS
78 #include <libgnomevfs/gnome-vfs-mime-utils.h>
80 #include <libgnomevfs/gnome-vfs-mime.h>
82 #include <modest-utils.h>
83 #include "modest-maemo-utils.h"
84 #include <modest-ui-constants.h>
87 #define DEFAULT_FONT_SIZE 3
88 #define DEFAULT_FONT 2
89 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
90 #define DEFAULT_MAIN_VBOX_SPACING 6
91 #define SUBJECT_MAX_LENGTH 1000
92 #define IMAGE_MAX_WIDTH 560
93 #define DEFAULT_FONT_SCALE 1.5
94 #define ATTACHMENT_BUTTON_WIDTH 118
96 static gboolean is_wp_text_buffer_started = FALSE;
98 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
99 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
100 static void modest_msg_edit_window_finalize (GObject *obj);
102 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
103 static void body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
104 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
106 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
107 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
108 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
109 static void text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
110 GtkTextIter *start, GtkTextIter *end,
112 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
113 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
114 static void subject_field_insert_text (GtkEditable *editable,
116 gint new_text_length,
118 ModestMsgEditWindow *window);
119 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
121 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
123 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
124 ModestRecptEditor *editor);
125 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
126 ModestMsgEditWindow *window);
128 /* ModestWindow methods implementation */
129 static void modest_msg_edit_window_disconnect_signals (ModestWindow *window);
130 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
131 gboolean show_toolbar);
132 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
134 ModestMsgEditWindow *window);
135 static void modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window);
136 static void subject_field_move_cursor (GtkEntry *entry,
137 GtkMovementStep step,
141 static void update_window_title (ModestMsgEditWindow *window);
144 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
145 ModestMsgEditWindow *window);
146 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
147 ModestMsgEditWindow *window);
148 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
150 GtkTextIter *match_start,
151 GtkTextIter *match_end);
153 static void remove_tags (WPTextBuffer *buffer);
155 static void on_account_removed (TnyAccountStore *account_store,
159 static void init_window (ModestMsgEditWindow *obj);
161 gboolean scroll_drag_timeout (gpointer userdata);
162 static void correct_scroll (ModestMsgEditWindow *w);
163 static void correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused);
164 static void text_buffer_end_user_action (GtkTextBuffer *buffer,
165 ModestMsgEditWindow *userdata);
166 static void text_buffer_mark_set (GtkTextBuffer *buffer,
169 ModestMsgEditWindow *userdata);
170 static void on_message_settings (GtkAction *action,
171 ModestMsgEditWindow *window);
172 static void setup_menu (ModestMsgEditWindow *self);
174 static void from_field_changed (HildonPickerButton *button,
175 ModestMsgEditWindow *self);
176 static void font_size_clicked (GtkToolButton *button,
177 ModestMsgEditWindow *window);
178 static void font_face_clicked (GtkToolButton *button,
179 ModestMsgEditWindow *window);
180 static void update_signature (ModestMsgEditWindow *self,
181 const gchar *old_account,
182 const gchar *new_account);
183 static void DEBUG_BUFFER (WPTextBuffer *buffer)
187 g_message ("BEGIN BUFFER OF SIZE %d", gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (buffer)));
189 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
190 while (!gtk_text_iter_is_end (&iter)) {
191 GString *output = g_string_new ("");
192 GSList *toggled_tags;
195 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
196 g_string_append_printf (output, "%d: CLOSED [ ", gtk_text_iter_get_offset (&iter));
197 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
198 GtkTextTag *tag = (GtkTextTag *) node->data;
200 g_object_get (G_OBJECT (tag), "name", &name, NULL);
201 output = g_string_append (output, name);
202 g_string_append (output, " ");
204 output = g_string_append (output, "] OPENED [ ");
205 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
206 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
207 GtkTextTag *tag = (GtkTextTag *) node->data;
209 g_object_get (G_OBJECT (tag), "name", &name, NULL);
210 output = g_string_append (output, name);
211 g_string_append (output, " ");
213 output = g_string_append (output, "]\n");
214 g_message ("%s", output->str);
215 g_string_free (output, TRUE);
216 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
218 g_message ("END BUFFER");
222 static const GtkActionEntry hildon2_msg_edit_action_entries [] = {
223 { "MessageSettings", NULL, N_("mcen_me_message_settings"), NULL, NULL, G_CALLBACK (on_message_settings)},
227 /* static gboolean */
228 /* on_key_pressed (GtkWidget *self, */
229 /* GdkEventKey *event, */
230 /* gpointer user_data); */
232 /* list my signals */
239 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
240 struct _ModestMsgEditWindowPrivate {
242 GtkWidget *header_box;
244 ModestPairList *from_field_protos;
245 GtkWidget *from_field;
246 gchar *last_from_account;
247 gchar *original_account_name;
252 gchar *original_mailbox;
256 GtkWidget *bcc_field;
257 GtkWidget *subject_field;
258 GtkWidget *attachments_view;
259 GtkWidget *priority_icon;
260 GtkWidget *subject_box;
261 GtkWidget *add_attachment_button;
263 GtkWidget *cc_caption;
264 GtkWidget *bcc_caption;
265 gboolean update_caption_visibility;
266 GtkWidget *attachments_caption;
268 GtkTextBuffer *text_buffer;
270 GtkWidget *font_size_toolitem;
271 GtkWidget *font_face_toolitem;
272 GtkWidget *font_color_button;
273 GtkWidget *font_color_toolitem;
274 GSList *font_items_group;
275 GtkTreeModel *faces_model;
276 gint current_face_index;
277 GtkWidget *font_tool_button_label;
278 GtkTreeModel *sizes_model;
279 gint current_size_index;
280 GtkWidget *size_tool_button_label;
282 GtkWidget *find_toolbar;
285 GtkWidget *font_dialog;
288 guint correct_scroll_idle;
289 guint scroll_drag_timeout_id;
293 TnyList *attachments;
298 TnyHeaderFlags priority_flags;
300 gboolean can_undo, can_redo;
301 gulong clipboard_change_handler_id;
302 gulong default_clipboard_change_handler_id;
303 gulong account_removed_handler_id;
304 guint clipboard_owner_idle;
305 gchar *clipboard_text;
314 GtkWidget *cc_button;
315 GtkWidget *bcc_button;
318 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
319 MODEST_TYPE_MSG_EDIT_WINDOW, \
320 ModestMsgEditWindowPrivate))
322 static GtkWindowClass *parent_class = NULL;
324 /* uncomment the following if you have defined any signals */
325 /* static guint signals[LAST_SIGNAL] = {0}; */
328 modest_msg_edit_window_get_type (void)
330 static GType my_type = 0;
332 static const GTypeInfo my_info = {
333 sizeof(ModestMsgEditWindowClass),
334 NULL, /* base init */
335 NULL, /* base finalize */
336 (GClassInitFunc) modest_msg_edit_window_class_init,
337 NULL, /* class finalize */
338 NULL, /* class data */
339 sizeof(ModestMsgEditWindow),
341 (GInstanceInitFunc) modest_msg_edit_window_init,
344 my_type = g_type_register_static (MODEST_TYPE_HILDON2_WINDOW,
345 "ModestMsgEditWindow",
353 save_state (ModestWindow *self)
355 modest_widget_memory_save (modest_runtime_get_conf(),
356 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
361 restore_settings (ModestMsgEditWindow *self)
363 ModestConf *conf = NULL;
365 conf = modest_runtime_get_conf ();
367 /* Dim at start clipboard actions */
368 modest_widget_memory_restore (conf, G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
373 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
375 GObjectClass *gobject_class;
376 ModestWindowClass *modest_window_class;
377 gobject_class = (GObjectClass*) klass;
378 modest_window_class = (ModestWindowClass*) klass;
380 parent_class = g_type_class_peek_parent (klass);
381 gobject_class->finalize = modest_msg_edit_window_finalize;
383 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
384 modest_window_class->save_state_func = save_state;
385 modest_window_class->disconnect_signals_func = modest_msg_edit_window_disconnect_signals;
387 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
391 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
393 ModestMsgEditWindowPrivate *priv;
394 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
396 priv->msg_body = NULL;
397 priv->from_field = NULL;
398 priv->to_field = NULL;
399 priv->cc_field = NULL;
400 priv->bcc_field = NULL;
401 priv->subject_field = NULL;
402 priv->attachments = TNY_LIST (tny_simple_list_new ());
403 priv->images = TNY_LIST (tny_simple_list_new ());
404 priv->images_size = 0;
405 priv->images_count = 0;
408 priv->cc_caption = NULL;
409 priv->bcc_caption = NULL;
410 priv->update_caption_visibility = FALSE;
412 priv->priority_flags = 0;
414 priv->find_toolbar = NULL;
415 priv->last_search = NULL;
417 priv->draft_msg = NULL;
418 priv->outbox_msg = NULL;
419 priv->msg_uid = NULL;
421 priv->can_undo = FALSE;
422 priv->can_redo = FALSE;
423 priv->clipboard_change_handler_id = 0;
424 priv->default_clipboard_change_handler_id = 0;
425 priv->account_removed_handler_id = 0;
426 priv->clipboard_owner_idle = 0;
427 priv->clipboard_text = NULL;
430 priv->scroll_drag_timeout_id = 0;
431 priv->correct_scroll_idle = 0;
432 priv->last_upper = 0.0;
434 priv->font_dialog = NULL;
435 priv->app_menu = NULL;
437 priv->references = NULL;
438 priv->in_reply_to = NULL;
440 if (!is_wp_text_buffer_started) {
441 is_wp_text_buffer_started = TRUE;
442 wp_text_buffer_library_init ();
447 hildon_program_add_window (hildon_program_get_instance(),
451 static gboolean account_is_multimailbox (const gchar *account_name, ModestProtocol **mmb_protocol)
453 gchar *transport_account;
454 gboolean result = FALSE;
457 *mmb_protocol = NULL;
459 transport_account = modest_account_mgr_get_server_account_name (modest_runtime_get_account_mgr (),
461 TNY_ACCOUNT_TYPE_TRANSPORT);
462 if (transport_account) {
464 ModestProtocolRegistry *registry;
466 registry = modest_runtime_get_protocol_registry ();
468 proto = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), transport_account,
469 MODEST_ACCOUNT_PROTO, TRUE);
471 ModestProtocol *protocol =
472 modest_protocol_registry_get_protocol_by_name (registry,
473 MODEST_PROTOCOL_REGISTRY_TRANSPORT_PROTOCOLS,
476 modest_protocol_registry_protocol_type_has_tag
478 modest_protocol_get_type_id (protocol),
479 MODEST_PROTOCOL_REGISTRY_MULTI_MAILBOX_PROVIDER_PROTOCOLS)) {
481 *mmb_protocol = protocol;
492 multimailbox_get_default_mailbox (const gchar *account_name)
494 gchar *transport_account;
495 gchar *result = NULL;
497 transport_account = modest_account_mgr_get_server_account_name (modest_runtime_get_account_mgr (),
499 TNY_ACCOUNT_TYPE_TRANSPORT);
500 if (transport_account) {
502 ModestProtocolRegistry *registry;
504 registry = modest_runtime_get_protocol_registry ();
506 proto = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), transport_account,
507 MODEST_ACCOUNT_PROTO, TRUE);
509 ModestProtocol *protocol =
510 modest_protocol_registry_get_protocol_by_name (registry,
511 MODEST_PROTOCOL_REGISTRY_TRANSPORT_PROTOCOLS,
513 if (MODEST_ACCOUNT_PROTOCOL (protocol)) {
514 ModestPairList *pair_list;
516 pair_list = modest_account_protocol_get_from_list (MODEST_ACCOUNT_PROTOCOL (protocol),
519 ModestPair *pair = (ModestPair *) pair_list->data;
520 result = g_strdup ((const gchar *) pair->first);
521 modest_pair_list_free (pair_list);
532 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
534 static ModestPairList*
535 get_transports (void)
537 GSList *transports = NULL;
539 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
540 GSList *accounts = modest_account_mgr_account_names (account_mgr,
541 TRUE /* only enabled accounts. */);
543 GSList *cursor = accounts;
545 gchar *account_name = cursor->data;
548 gchar *transport_account;
549 gboolean multi_mailbox = FALSE;
550 ModestProtocol *protocol = NULL;
552 if (account_is_multimailbox (account_name, &protocol)) {
554 transport_account = modest_account_mgr_get_server_account_name
555 (modest_runtime_get_account_mgr (),
557 TNY_ACCOUNT_TYPE_TRANSPORT);
558 if (protocol && MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
559 ModestPairList *pair_list;
560 pair_list = modest_account_protocol_get_from_list (MODEST_ACCOUNT_PROTOCOL (protocol),
563 transports = g_slist_concat (transports, pair_list);
564 multi_mailbox = TRUE;
569 if (!multi_mailbox) {
570 gchar *from_string = NULL;
572 from_string = modest_account_mgr_get_from_string (account_mgr,
574 if (from_string && account_name) {
575 gchar *name = account_name;
576 ModestPair *pair = modest_pair_new ((gpointer) name,
577 (gpointer) from_string , TRUE);
578 transports = g_slist_prepend (transports, pair);
583 cursor = cursor->next;
585 g_slist_free (accounts); /* only free the accounts, not the elements,
586 * because they are used in the pairlist */
590 static void window_focus (GtkWindow *window,
594 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
598 scroll_drag_timeout (gpointer userdata)
600 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
601 ModestMsgEditWindowPrivate *priv;
603 /* It could happen that the window was already closed */
604 if (!GTK_WIDGET_VISIBLE (win))
607 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
609 correct_scroll_without_drag_check (win, TRUE);
611 priv->scroll_drag_timeout_id = 0;
617 correct_scroll_without_drag_check_idle (gpointer userdata)
619 ModestMsgEditWindow *w = (ModestMsgEditWindow *) userdata;
620 ModestMsgEditWindowPrivate *priv;
622 GdkRectangle rectangle;
623 gint offset_min, offset_max;
627 /* It could happen that the window was already closed */
628 if (!GTK_WIDGET_VISIBLE (w))
631 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
633 insert = gtk_text_buffer_get_insert (priv->text_buffer);
634 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
636 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
637 offset_min = priv->msg_body->allocation.y + rectangle.y;
638 offset_max = offset_min + rectangle.height;
640 vadj = hildon_pannable_area_get_vadjustment (HILDON_PANNABLE_AREA (priv->pannable));
641 offset_min = MAX (offset_min - 48, 0);
642 offset_max = MIN (offset_max + 48, vadj->upper);
644 gtk_adjustment_clamp_page (vadj, (gdouble) offset_min, (gdouble) offset_max);
646 priv->correct_scroll_idle = 0;
651 correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused)
653 ModestMsgEditWindowPrivate *priv;
655 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
657 if (only_if_focused && !gtk_widget_is_focus (priv->msg_body))
660 if (priv->correct_scroll_idle > 0) {
664 priv->correct_scroll_idle = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
665 (GSourceFunc) correct_scroll_without_drag_check_idle,
671 correct_scroll (ModestMsgEditWindow *w)
673 ModestMsgEditWindowPrivate *priv;
675 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
676 if (gtk_grab_get_current () == priv->msg_body) {
677 if (priv->scroll_drag_timeout_id == 0) {
678 priv->scroll_drag_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
680 (GSourceFunc) scroll_drag_timeout,
687 correct_scroll_without_drag_check (w, TRUE);
691 text_buffer_end_user_action (GtkTextBuffer *buffer,
692 ModestMsgEditWindow *userdata)
695 correct_scroll (userdata);
699 text_buffer_mark_set (GtkTextBuffer *buffer,
702 ModestMsgEditWindow *userdata)
704 gtk_text_buffer_begin_user_action (buffer);
705 gtk_text_buffer_end_user_action (buffer);
709 cut_clipboard_check (GtkTextView *text_view,
712 GtkTextBuffer *buffer;
714 buffer = gtk_text_view_get_buffer (text_view);
715 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
716 g_signal_stop_emission_by_name ((gpointer )text_view, "cut-clipboard");
721 copy_clipboard_check (GtkTextView *text_view,
724 GtkTextBuffer *buffer;
726 buffer = gtk_text_view_get_buffer (text_view);
727 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
728 g_signal_stop_emission_by_name ((gpointer )text_view, "copy-clipboard");
733 attachment_deleted (ModestAttachmentsView *attachments_view,
736 modest_msg_edit_window_remove_attachments (MODEST_MSG_EDIT_WINDOW (user_data),
741 connect_signals (ModestMsgEditWindow *obj)
743 ModestMsgEditWindowPrivate *priv;
745 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
747 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
748 G_CALLBACK (text_buffer_refresh_attributes), obj);
749 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
750 G_CALLBACK (text_buffer_can_undo), obj);
751 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
752 G_CALLBACK (text_buffer_can_redo), obj);
753 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
754 G_CALLBACK (body_changed), obj);
755 g_signal_connect (G_OBJECT (priv->text_buffer), "modified-changed",
756 G_CALLBACK (body_changed), obj);
757 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
758 G_CALLBACK (text_buffer_end_user_action), obj);
759 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
760 G_CALLBACK (text_buffer_mark_set), obj);
761 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
762 G_CALLBACK (text_buffer_apply_tag), obj);
763 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
764 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
765 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
766 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
767 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
768 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
770 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
771 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
772 g_signal_connect (G_OBJECT (priv->from_field), "value-changed",
773 G_CALLBACK (from_field_changed), obj);
775 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
776 G_CALLBACK (msg_body_focus), obj);
777 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
778 G_CALLBACK (msg_body_focus), obj);
779 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
780 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
781 "changed", G_CALLBACK (recpt_field_changed), obj);
782 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
783 "changed", G_CALLBACK (recpt_field_changed), obj);
784 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
785 "changed", G_CALLBACK (recpt_field_changed), obj);
786 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
787 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
788 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
790 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
791 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
793 priv->clipboard_change_handler_id =
794 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
795 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
796 priv->default_clipboard_change_handler_id =
797 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
798 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
800 g_signal_connect (G_OBJECT (priv->msg_body), "cut-clipboard", G_CALLBACK (cut_clipboard_check), NULL);
801 g_signal_connect (G_OBJECT (priv->msg_body), "copy-clipboard", G_CALLBACK (copy_clipboard_check), NULL);
802 g_signal_connect (G_OBJECT (priv->attachments_view), "delete", G_CALLBACK (attachment_deleted), obj);
806 init_wp_text_view_style ()
808 static gboolean initialized = FALSE;
811 gtk_rc_parse_string ("class \"WPTextView\" style \"fremantle-textview\"");
817 init_window (ModestMsgEditWindow *obj)
819 GtkWidget *to_caption, *subject_caption;
820 GtkWidget *main_vbox;
821 GtkWidget *add_attachment_align;
822 ModestMsgEditWindowPrivate *priv;
823 GtkActionGroup *action_group;
824 ModestWindowPrivate *parent_priv;
825 GdkPixbuf *window_icon = NULL;
826 GError *error = NULL;
828 GtkSizeGroup *title_size_group;
829 GtkSizeGroup *value_size_group;
830 GtkWidget *attachment_icon;
831 GtkWidget *window_box;
832 GtkWidget *window_align;
833 #if (GTK_MINOR_VERSION >= 10)
834 GdkAtom deserialize_type;
837 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
838 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
840 parent_priv->ui_manager = gtk_ui_manager_new();
841 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
842 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
844 /* Add common actions */
845 gtk_action_group_add_actions (action_group,
846 modest_msg_edit_action_entries,
847 G_N_ELEMENTS (modest_msg_edit_action_entries),
849 gtk_action_group_add_actions (action_group,
850 hildon2_msg_edit_action_entries,
851 G_N_ELEMENTS (hildon2_msg_edit_action_entries),
853 gtk_action_group_add_toggle_actions (action_group,
854 modest_msg_edit_toggle_action_entries,
855 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
857 gtk_action_group_add_radio_actions (action_group,
858 modest_msg_edit_alignment_radio_action_entries,
859 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
861 G_CALLBACK (modest_ui_actions_on_change_justify),
863 gtk_action_group_add_radio_actions (action_group,
864 modest_msg_edit_priority_action_entries,
865 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
867 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
869 gtk_action_group_add_radio_actions (action_group,
870 modest_msg_edit_file_format_action_entries,
871 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
872 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
873 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
875 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
876 g_object_unref (action_group);
878 /* Load the UI definition */
879 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
882 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
883 g_clear_error (&error);
886 /* Add accelerators */
887 gtk_window_add_accel_group (GTK_WINDOW (obj),
888 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
890 parent_priv->menubar = NULL;
892 title_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
893 value_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
895 /* Note: This ModestPairList* must exist for as long as the picker
896 * that uses it, because the ModestSelectorPicker uses the ID opaquely,
897 * so it can't know how to manage its memory. */
898 priv->from_field = modest_selector_picker_new (MODEST_EDITABLE_SIZE,
899 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
901 modest_maemo_utils_set_hbutton_layout (title_size_group, value_size_group,
902 _("mail_va_from"), priv->from_field);
904 priv->to_field = modest_recpt_editor_new ();
905 priv->cc_field = modest_recpt_editor_new ();
906 priv->bcc_field = modest_recpt_editor_new ();
907 priv->subject_box = gtk_hbox_new (FALSE, MODEST_MARGIN_NONE);
908 priv->priority_icon = gtk_image_new ();
909 gtk_box_pack_start (GTK_BOX (priv->subject_box), priv->priority_icon, FALSE, FALSE, 0);
910 priv->subject_field = hildon_entry_new (MODEST_EDITABLE_SIZE);
911 gtk_entry_set_max_length (GTK_ENTRY (priv->subject_field) ,SUBJECT_MAX_LENGTH);
912 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
913 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
914 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
915 gtk_box_pack_start (GTK_BOX (priv->subject_box), priv->subject_field, TRUE, TRUE, 0);
916 priv->add_attachment_button = hildon_button_new (MODEST_EDITABLE_SIZE, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
917 gtk_widget_set_size_request (priv->add_attachment_button, ATTACHMENT_BUTTON_WIDTH, -1);
918 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
919 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
920 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, HILDON_ICON_SIZE_FINGER);
921 hildon_button_set_image (HILDON_BUTTON (priv->add_attachment_button), attachment_icon);
922 add_attachment_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
923 gtk_alignment_set_padding (GTK_ALIGNMENT (add_attachment_align), 0, 0, MODEST_MARGIN_DEFAULT, 0);
924 gtk_container_add (GTK_CONTAINER (add_attachment_align), priv->add_attachment_button);
925 gtk_box_pack_start (GTK_BOX (priv->subject_box), add_attachment_align, FALSE, FALSE, 0);
926 priv->attachments_view = modest_attachments_view_new (NULL);
927 modest_attachments_view_set_style (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
928 MODEST_ATTACHMENTS_VIEW_STYLE_NO_FOCUS);
930 priv->header_box = gtk_vbox_new (FALSE, 0);
932 to_caption = modest_maemo_utils_create_captioned_with_size_type
933 (title_size_group, value_size_group,
934 _("mail_va_to"), FALSE, priv->to_field,
935 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
936 priv->cc_caption = modest_maemo_utils_create_captioned_with_size_type
937 (title_size_group, value_size_group,
938 _("mail_va_cc"), FALSE, priv->cc_field,
939 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
940 priv->bcc_caption = modest_maemo_utils_create_captioned_with_size_type
941 (title_size_group, value_size_group,
942 _("mail_va_hotfix1"), FALSE, priv->bcc_field,
943 HILDON_SIZE_AUTO_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
944 subject_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
945 _("mail_va_subject"), FALSE, priv->subject_box);
946 priv->attachments_caption = modest_maemo_utils_create_captioned_with_size_type (title_size_group, value_size_group,
947 _("mail_va_attachment"),
949 priv->attachments_view,
950 HILDON_SIZE_AUTO_WIDTH |
951 HILDON_SIZE_AUTO_HEIGHT);
952 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), value_size_group); */
953 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), value_size_group); */
954 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), value_size_group); */
955 g_object_unref (title_size_group);
956 g_object_unref (value_size_group);
958 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->from_field, FALSE, FALSE, 0);
959 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
960 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
961 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
962 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
963 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
964 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
966 init_wp_text_view_style ();
968 priv->msg_body = modest_wp_text_view_new ();
971 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
972 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
973 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
974 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
975 #if (GTK_MINOR_VERSION >= 10)
976 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), NULL);
977 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
979 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
980 deserialize_type, TRUE);
982 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
984 priv->find_toolbar = hildon_find_toolbar_new (NULL);
985 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
987 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
989 priv->pannable = hildon_pannable_area_new ();
991 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
992 window_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
993 gtk_alignment_set_padding (GTK_ALIGNMENT (window_align), 0, 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DEFAULT);
995 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
996 gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 0);
997 gtk_container_add (GTK_CONTAINER (window_align), main_vbox);
999 hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA (priv->pannable), window_align);
1000 gtk_widget_show_all (GTK_WIDGET(priv->pannable));
1002 window_box = gtk_vbox_new (FALSE, 0);
1003 gtk_container_add (GTK_CONTAINER(obj), window_box);
1005 gtk_box_pack_start (GTK_BOX (window_box), priv->pannable, TRUE, TRUE, 0);
1007 /* Set window icon */
1008 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
1010 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
1011 g_object_unref (window_icon);
1016 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
1018 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1020 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
1021 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
1022 priv->clipboard_change_handler_id))
1023 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
1024 priv->clipboard_change_handler_id);
1025 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
1026 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
1027 priv->default_clipboard_change_handler_id))
1028 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
1029 priv->default_clipboard_change_handler_id);
1031 if (priv->account_removed_handler_id &&
1032 g_signal_handler_is_connected (modest_runtime_get_account_store (),
1033 priv->account_removed_handler_id))
1034 g_signal_handler_disconnect(modest_runtime_get_account_store (),
1035 priv->account_removed_handler_id);
1039 modest_msg_edit_window_finalize (GObject *obj)
1041 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1043 /* Sanity check: shouldn't be needed, the window mgr should
1044 call this function before */
1045 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
1047 if (priv->font_dialog != NULL) {
1048 gtk_dialog_response (GTK_DIALOG (priv->font_dialog), GTK_RESPONSE_NONE);
1051 if (priv->clipboard_text != NULL) {
1052 g_free (priv->clipboard_text);
1053 priv->clipboard_text = NULL;
1056 if (priv->draft_msg != NULL) {
1057 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
1058 if (TNY_IS_HEADER (header)) {
1059 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1060 modest_window_mgr_unregister_header (mgr, header);
1062 g_object_unref (priv->draft_msg);
1063 priv->draft_msg = NULL;
1065 if (priv->outbox_msg != NULL) {
1066 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
1067 if (TNY_IS_HEADER (header)) {
1068 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1069 modest_window_mgr_unregister_header (mgr, header);
1071 g_object_unref (priv->outbox_msg);
1072 priv->outbox_msg = NULL;
1074 if (priv->correct_scroll_idle > 0) {
1075 g_source_remove (priv->correct_scroll_idle);
1076 priv->correct_scroll_idle = 0;
1078 if (priv->scroll_drag_timeout_id > 0) {
1079 g_source_remove (priv->scroll_drag_timeout_id);
1080 priv->scroll_drag_timeout_id = 0;
1082 if (priv->clipboard_owner_idle > 0) {
1083 g_source_remove (priv->clipboard_owner_idle);
1084 priv->clipboard_owner_idle = 0;
1086 if (priv->original_account_name)
1087 g_free (priv->original_account_name);
1088 if (priv->original_mailbox)
1089 g_free (priv->original_mailbox);
1090 g_free (priv->msg_uid);
1091 g_free (priv->last_search);
1092 g_free (priv->references);
1093 g_free (priv->in_reply_to);
1094 g_object_unref (priv->faces_model);
1095 g_object_unref (priv->sizes_model);
1096 g_object_unref (priv->attachments);
1097 g_object_unref (priv->images);
1099 /* This had to stay alive for as long as the picker that used it: */
1100 modest_pair_list_free (priv->from_field_protos);
1102 G_OBJECT_CLASS(parent_class)->finalize (obj);
1106 pixbuf_size_prepared (GdkPixbufLoader *loader,
1109 ModestMsgEditWindow *self)
1111 gint new_height, new_width;
1114 new_height = height;
1118 if (width > IMAGE_MAX_WIDTH) {
1119 new_height = height * IMAGE_MAX_WIDTH / width;
1120 new_width = IMAGE_MAX_WIDTH;
1123 gdk_pixbuf_loader_set_size (loader, new_width, new_height);
1127 pixbuf_from_stream (TnyStream *stream,
1128 const gchar *mime_type,
1129 guint64 *stream_size,
1130 ModestMsgEditWindow *self)
1132 GdkPixbufLoader *loader;
1135 GError *error = NULL;
1139 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1141 if (loader == NULL) {
1146 g_signal_connect (G_OBJECT (loader), "size-prepared", G_CALLBACK (pixbuf_size_prepared), self);
1148 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), TRUE);
1150 tny_stream_reset (TNY_STREAM (stream));
1151 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1152 unsigned char read_buffer[128];
1154 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1156 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, &error)) {
1159 /* Allow some UI responsiveness */
1160 while (gtk_events_pending ())
1161 gtk_main_iteration ();
1163 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), FALSE);
1165 gdk_pixbuf_loader_close (loader, &error);
1168 g_error_free (error);
1169 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1171 g_object_ref (pixbuf);
1172 g_object_unref (loader);
1177 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1178 GdkPixbuf *new_pixbuf;
1180 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1181 gdk_pixbuf_get_width (pixbuf);
1182 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1183 g_object_unref (pixbuf);
1184 pixbuf = new_pixbuf;
1188 *stream_size = size;
1194 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1196 ModestMsgEditWindowPrivate *priv;
1199 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1201 g_object_ref (self);
1202 for (iter = tny_list_create_iterator (attachments);
1203 !tny_iterator_is_done (iter);
1204 tny_iterator_next (iter)) {
1205 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1206 const gchar *cid = tny_mime_part_get_content_id (part);
1207 const gchar *mime_type = tny_mime_part_get_content_type (part);
1208 if ((cid != NULL)&&(mime_type != NULL)) {
1209 guint64 stream_size;
1210 TnyStream *stream = tny_mime_part_get_decoded_stream (part);
1211 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size, self);
1214 g_object_unref (stream);
1216 if (pixbuf != NULL) {
1217 priv->images_count ++;
1218 priv->images_size += stream_size;
1219 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1220 g_object_unref (pixbuf);
1223 g_object_unref (part);
1225 g_object_unref (iter);
1226 g_object_unref (self);
1230 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1232 TnyMimePart *parent = NULL;
1233 const gchar *content_type = NULL;
1234 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1236 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1238 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1239 parent = g_object_ref (msg);
1240 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1241 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1244 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1245 iter = tny_list_create_iterator (parts);
1246 while (!tny_iterator_is_done (iter)) {
1248 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1249 content_type = tny_mime_part_get_content_type (part);
1250 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1254 g_object_unref (part);
1256 tny_iterator_next (iter);
1258 g_object_unref (iter);
1259 g_object_unref (parts);
1262 if (parent != NULL) {
1263 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1266 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1267 iter = tny_list_create_iterator (parts);
1268 while (!tny_iterator_is_done (iter)) {
1270 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1271 content_type = tny_mime_part_get_content_type (part);
1272 if (content_type && g_str_has_prefix (content_type, "image/")) {
1273 tny_list_prepend (priv->images, (GObject *) part);
1275 g_object_unref (part);
1276 tny_iterator_next (iter);
1278 g_object_unref (iter);
1279 g_object_unref (parts);
1280 g_object_unref (parent);
1285 update_next_cid (ModestMsgEditWindow *self, TnyList *attachments)
1288 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1290 for (iter = tny_list_create_iterator (attachments) ;
1291 !tny_iterator_is_done (iter);
1292 tny_iterator_next (iter)) {
1293 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1294 const gchar *cid = tny_mime_part_get_content_id (part);
1296 char *invalid = NULL;
1297 gint int_cid = strtol (cid, &invalid, 10);
1298 if ((invalid != NULL) && (*invalid == '\0') && (int_cid >= priv->next_cid)) {
1299 priv->next_cid = int_cid + 1;
1302 g_object_unref (part);
1304 g_object_unref (iter);
1308 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1311 gchar *to, *cc, *bcc, *subject;
1313 ModestMsgEditWindowPrivate *priv;
1314 ModestWindowPrivate *parent_priv;
1316 TnyHeaderFlags priority_flags;
1317 TnyFolder *msg_folder;
1318 gboolean is_html = FALSE;
1319 gboolean field_view_set;
1321 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1322 g_return_if_fail (TNY_IS_MSG (msg));
1324 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1325 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1327 header = tny_msg_get_header (msg);
1328 to = tny_header_dup_to (header);
1329 cc = tny_header_dup_cc (header);
1330 bcc = tny_header_dup_bcc (header);
1331 subject = tny_header_dup_subject (header);
1333 modest_tny_msg_get_references (TNY_MSG (msg), NULL, &(priv->references), &(priv->in_reply_to));
1334 priority_flags = tny_header_get_priority (header);
1337 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1339 field_view_set = TRUE;
1341 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1342 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1343 gtk_widget_show (priv->cc_caption);
1344 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1345 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1346 gtk_widget_hide (priv->cc_caption);
1347 field_view_set = FALSE;
1349 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->cc_button), field_view_set);
1351 field_view_set = TRUE;
1353 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1354 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1355 gtk_widget_show (priv->bcc_caption);
1356 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1357 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1358 gtk_widget_hide (priv->bcc_caption);
1359 field_view_set = FALSE;
1361 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->bcc_button), field_view_set);
1365 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1366 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1369 update_window_title (self);
1371 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1372 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1374 if ((body == NULL)||(body[0] == '\0')) {
1376 body = modest_text_utils_convert_to_html ("");
1379 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1380 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1383 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1386 /* Add attachments to the view */
1387 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1388 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1389 if (tny_list_get_length (priv->attachments) == 0) {
1390 gtk_widget_hide (priv->attachments_caption);
1392 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1393 gtk_widget_show_all (priv->attachments_caption);
1395 get_related_images (self, msg);
1396 update_next_cid (self, priv->attachments);
1397 update_next_cid (self, priv->images);
1398 replace_with_images (self, priv->images);
1400 if (preserve_is_rich && !is_html) {
1401 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1402 /* Get the default format required from configuration */
1403 } else if (!preserve_is_rich && !modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1404 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1407 /* Set the default focus depending on having already a To: field or not */
1408 if ((!to)||(*to == '\0')) {
1409 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1411 gtk_widget_grab_focus (priv->msg_body);
1414 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1416 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1417 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1419 modest_msg_edit_window_set_modified (self, FALSE);
1421 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1422 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1423 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1424 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1426 if (priv->msg_uid) {
1427 g_free (priv->msg_uid);
1428 priv->msg_uid = NULL;
1431 /* we should set a reference to the incoming message if it is a draft */
1432 msg_folder = tny_msg_get_folder (msg);
1434 if (modest_tny_folder_is_local_folder (msg_folder)) {
1435 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1436 if (type == TNY_FOLDER_TYPE_INVALID)
1437 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1439 if (type == TNY_FOLDER_TYPE_DRAFTS)
1440 priv->draft_msg = g_object_ref(msg);
1441 if (type == TNY_FOLDER_TYPE_OUTBOX)
1442 priv->outbox_msg = g_object_ref(msg);
1443 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1445 g_object_unref (msg_folder);
1456 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1458 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1459 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1460 GtkWidget *placeholder;
1461 GtkWidget *tool_item;
1466 GtkWidget *sizes_menu;
1467 GtkWidget *fonts_menu;
1473 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1474 gtk_toolbar_set_show_arrow (GTK_TOOLBAR (parent_priv->toolbar), FALSE);
1475 gtk_toolbar_set_icon_size (GTK_TOOLBAR (parent_priv->toolbar), HILDON_ICON_SIZE_FINGER);
1476 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1478 /* Font color placeholder */
1479 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1480 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1483 priv->font_color_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1484 priv->font_color_button = hildon_color_button_new ();
1485 gtk_widget_set_size_request (priv->font_color_button, -1, 48);
1486 GTK_WIDGET_UNSET_FLAGS (priv->font_color_toolitem, GTK_CAN_FOCUS);
1487 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1488 gtk_container_add (GTK_CONTAINER (priv->font_color_toolitem), priv->font_color_button);
1489 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1490 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1491 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->font_color_toolitem), insert_index);
1492 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1494 G_CALLBACK (modest_msg_edit_window_color_button_change),
1497 /* Font size and face placeholder */
1498 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1499 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1501 tool_item = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
1502 priv->size_tool_button_label = gtk_label_new (NULL);
1503 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1504 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1505 size_text, "</span>", NULL);
1506 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1507 gtk_misc_set_alignment (GTK_MISC (priv->size_tool_button_label), 1.0, 0.5);
1509 hildon_helper_set_logical_font (priv->size_tool_button_label, "LargeSystemFont");
1510 hbox = gtk_hbox_new (MODEST_MARGIN_DEFAULT, FALSE);
1511 gtk_box_pack_start (GTK_BOX (hbox), priv->size_tool_button_label, TRUE, TRUE, 0);
1512 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1513 gtk_misc_set_alignment (GTK_MISC (arrow), 0.0, 0.5);
1514 gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
1515 gtk_widget_set_sensitive (arrow, FALSE);
1516 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), hbox);
1517 sizes_menu = gtk_menu_new ();
1518 priv->sizes_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
1519 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1522 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1523 gtk_list_store_append (GTK_LIST_STORE (priv->sizes_model), &iter);
1525 gtk_list_store_set (GTK_LIST_STORE (priv->sizes_model), &iter,
1529 if (wp_font_size[size_index] == 12)
1530 priv->current_size_index = size_index;
1534 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (font_size_clicked), window);
1535 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1536 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1537 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1538 priv->font_size_toolitem = tool_item;
1541 tool_item = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
1542 priv->font_tool_button_label = gtk_label_new (NULL);
1543 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1544 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1545 gtk_misc_set_alignment (GTK_MISC (priv->font_tool_button_label), 1.0, 0.5);
1547 hildon_helper_set_logical_font (priv->font_tool_button_label, "LargeSystemFont");
1548 hbox = gtk_hbox_new (MODEST_MARGIN_DEFAULT, FALSE);
1549 gtk_box_pack_start (GTK_BOX (hbox), priv->font_tool_button_label, TRUE, TRUE, 0);
1550 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1551 gtk_misc_set_alignment (GTK_MISC (arrow), 0.0, 0.5);
1552 gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
1553 gtk_widget_set_sensitive (arrow, FALSE);
1554 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), hbox);
1555 fonts_menu = gtk_menu_new ();
1556 priv->faces_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
1557 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1560 gtk_list_store_append (GTK_LIST_STORE (priv->faces_model), &iter);
1562 gtk_list_store_set (GTK_LIST_STORE (priv->faces_model), &iter,
1563 0, wp_get_font_name (font_index),
1566 if (font_index == DEFAULT_FONT)
1567 priv->current_face_index = font_index;
1569 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (font_face_clicked), window);
1570 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1571 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1572 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1573 priv->font_face_toolitem = tool_item;
1575 /* Set expand and homogeneous for remaining items */
1576 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
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/ActionsBold");
1580 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1581 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1582 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1583 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1584 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1586 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1587 will not show the tool items added to the placeholders) */
1588 gtk_widget_show_all (parent_priv->toolbar);
1590 /* Set the no show all *after* showing all items. We do not
1591 want the toolbar to be shown with a show all because it
1592 could go agains the gconf setting regarding showing or not
1593 the toolbar of the editor window */
1594 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1600 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, const gchar *mailbox, gboolean preserve_is_rich)
1603 ModestWindowPrivate *parent_priv;
1604 ModestMsgEditWindowPrivate *priv;
1605 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1606 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1607 ModestWindowMgr *mgr = NULL;
1609 g_return_val_if_fail (msg, NULL);
1610 g_return_val_if_fail (account_name, NULL);
1612 mgr = modest_runtime_get_window_mgr ();
1614 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1616 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1617 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1619 /* Menubar. Update the state of some toggles */
1620 priv->from_field_protos = get_transports ();
1621 priv->original_mailbox = NULL;
1622 modest_selector_picker_set_pair_list (MODEST_SELECTOR_PICKER (priv->from_field), priv->from_field_protos);
1623 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1624 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1625 if (mailbox && modest_pair_list_find_by_first_as_string (priv->from_field_protos, mailbox)) {
1626 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) mailbox);
1627 priv->original_mailbox = g_strdup (mailbox);
1628 } else if (account_is_multimailbox (account_name, NULL)) {
1629 /* We set the first mailbox as the active mailbox */
1630 priv->original_mailbox = multimailbox_get_default_mailbox (account_name);
1631 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field),
1632 (gpointer) priv->original_mailbox);
1634 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1636 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1637 hildon_button_set_title (HILDON_BUTTON (priv->from_field),
1639 hildon_button_set_value (HILDON_BUTTON (priv->from_field),
1640 hildon_touch_selector_get_current_text
1641 (HILDON_TOUCH_SELECTOR (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (priv->from_field)))));
1642 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1643 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1646 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1648 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1650 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1651 modest_window_set_active_mailbox (MODEST_WINDOW(obj), priv->original_mailbox);
1653 priv->original_account_name = (account_name) ? g_strdup (account_name) : NULL;
1655 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1656 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1657 /* Add common dimming rules */
1658 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1659 modest_msg_edit_window_toolbar_dimming_entries,
1660 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1661 MODEST_WINDOW (obj));
1662 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_toolitem,
1663 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1664 MODEST_WINDOW (obj));
1665 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1666 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1667 MODEST_WINDOW (obj));
1668 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1669 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1670 MODEST_WINDOW (obj));
1671 /* Insert dimming rules group for this window */
1672 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1673 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1675 /* Setup app menu */
1676 setup_menu (MODEST_MSG_EDIT_WINDOW (obj));
1678 /* Checks the dimming rules */
1679 g_object_unref (toolbar_rules_group);
1680 g_object_unref (clipboard_rules_group);
1681 gtk_widget_hide (priv->priority_icon);
1682 gtk_widget_queue_resize (priv->subject_box);
1683 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1686 update_signature (MODEST_MSG_EDIT_WINDOW (obj), mailbox, NULL);
1687 update_signature (MODEST_MSG_EDIT_WINDOW (obj), account_name, priv->last_from_account);
1689 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1691 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1692 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1693 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1694 priv->update_caption_visibility = TRUE;
1696 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1698 /* Track account-removed signal, this window should be closed
1699 in the case we're creating a mail associated to the account
1701 priv->account_removed_handler_id =
1702 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1704 G_CALLBACK(on_account_removed),
1707 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (MODEST_MSG_EDIT_WINDOW (obj));
1709 return (ModestWindow*) obj;
1713 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1715 GString **string_buffer = (GString **) user_data;
1717 *string_buffer = g_string_append (*string_buffer, buffer);
1723 * @result: A new string which should be freed with g_free().
1726 get_formatted_data (ModestMsgEditWindow *edit_window)
1728 ModestMsgEditWindowPrivate *priv;
1729 GString *string_buffer = g_string_new ("");
1731 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1733 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1735 modest_text_utils_hyperlinkify (string_buffer);
1737 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1739 return g_string_free (string_buffer, FALSE);
1744 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1747 const gchar *account_name;
1748 ModestMsgEditWindowPrivate *priv;
1749 TnyIterator *att_iter;
1750 const gchar *picker_active_id;
1752 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1754 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1756 picker_active_id = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1757 g_return_val_if_fail (picker_active_id, NULL);
1758 account_name = modest_utils_get_account_name_from_recipient (picker_active_id, NULL);
1760 /* don't free these (except from) */
1761 data = g_slice_new0 (MsgData);
1762 data->from = g_strdup ((gchar *) modest_selector_picker_get_active_display_name (MODEST_SELECTOR_PICKER (priv->from_field)));
1763 data->account_name = g_strdup (account_name);
1764 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1765 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1766 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1767 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1768 data->references = g_strdup (priv->references);
1769 data->in_reply_to = g_strdup (priv->in_reply_to);
1770 if (priv->draft_msg) {
1771 data->draft_msg = g_object_ref (priv->draft_msg);
1772 } else if (priv->outbox_msg) {
1773 data->draft_msg = g_object_ref (priv->outbox_msg);
1775 data->draft_msg = NULL;
1778 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1780 gtk_text_buffer_get_bounds (buf, &b, &e);
1781 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1783 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1784 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1786 data->html_body = NULL;
1788 /* deep-copy the data */
1789 att_iter = tny_list_create_iterator (priv->attachments);
1790 data->attachments = NULL;
1791 while (!tny_iterator_is_done (att_iter)) {
1792 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1793 if (!(TNY_IS_MIME_PART(part))) {
1794 g_warning ("strange data in attachment list");
1795 g_object_unref (part);
1796 tny_iterator_next (att_iter);
1799 data->attachments = g_list_append (data->attachments,
1801 tny_iterator_next (att_iter);
1803 g_object_unref (att_iter);
1805 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1806 att_iter = tny_list_create_iterator (priv->images);
1807 data->images = NULL;
1808 while (!tny_iterator_is_done (att_iter)) {
1809 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1811 if (!(TNY_IS_MIME_PART(part))) {
1812 g_warning ("strange data in attachment list");
1813 g_object_unref (part);
1814 tny_iterator_next (att_iter);
1817 cid = tny_mime_part_get_content_id (part);
1819 gchar *image_tag_id;
1820 GtkTextTag *image_tag;
1822 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1823 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1824 g_free (image_tag_id);
1826 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1828 ((gtk_text_iter_has_tag (&iter, image_tag))||
1829 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1830 data->images = g_list_append (data->images,
1831 g_object_ref (part));
1833 g_object_unref (part);
1834 tny_iterator_next (att_iter);
1836 g_object_unref (att_iter);
1838 data->priority_flags = priv->priority_flags;
1845 unref_gobject (GObject *obj, gpointer data)
1847 if (!G_IS_OBJECT(obj))
1849 g_object_unref (obj);
1853 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1856 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1864 g_free (data->from);
1865 g_free (data->subject);
1866 g_free (data->plain_body);
1867 g_free (data->html_body);
1868 g_free (data->account_name);
1869 g_free (data->references);
1870 g_free (data->in_reply_to);
1872 if (data->draft_msg != NULL) {
1873 g_object_unref (data->draft_msg);
1874 data->draft_msg = NULL;
1877 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1878 g_list_free (data->attachments);
1879 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1880 g_list_free (data->images);
1882 g_slice_free (MsgData, data);
1886 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1888 guint64 *parts_size)
1890 ModestMsgEditWindowPrivate *priv;
1892 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1894 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1896 /* TODO: add images */
1897 *parts_size += priv->images_size;
1898 *parts_count += priv->images_count;
1903 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1906 ModestMsgEditWindowPrivate *priv = NULL;
1907 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1909 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1911 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1913 return MODEST_MSG_EDIT_FORMAT_HTML;
1915 return MODEST_MSG_EDIT_FORMAT_TEXT;
1919 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1920 ModestMsgEditFormat format)
1922 ModestMsgEditWindowPrivate *priv;
1924 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1925 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1928 case MODEST_MSG_EDIT_FORMAT_HTML:
1929 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1931 case MODEST_MSG_EDIT_FORMAT_TEXT:
1932 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1935 g_return_if_reached ();
1939 ModestMsgEditFormatState *
1940 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1942 ModestMsgEditFormatState *format_state = NULL;
1943 ModestMsgEditWindowPrivate *priv;
1944 WPTextBufferFormat *buffer_format;
1946 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1948 buffer_format = g_new0 (WPTextBufferFormat, 1);
1949 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1951 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1953 format_state = g_new0 (ModestMsgEditFormatState, 1);
1954 format_state->bold = buffer_format->bold&0x1;
1955 format_state->italics = buffer_format->italic&0x1;
1956 format_state->bullet = buffer_format->bullet&0x1;
1957 format_state->color = buffer_format->color;
1958 format_state->font_size = buffer_format->font_size;
1959 format_state->font_family = wp_get_font_name (buffer_format->font);
1960 format_state->justification = buffer_format->justification;
1961 g_free (buffer_format);
1963 return format_state;
1968 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1969 const ModestMsgEditFormatState *format_state)
1971 ModestMsgEditWindowPrivate *priv;
1972 WPTextBufferFormat *buffer_format;
1973 WPTextBufferFormat *current_format;
1975 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1976 g_return_if_fail (format_state != NULL);
1978 buffer_format = g_new0 (WPTextBufferFormat, 1);
1979 current_format = g_new0 (WPTextBufferFormat, 1);
1981 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1982 gtk_widget_grab_focus (priv->msg_body);
1983 buffer_format->bold = (format_state->bold != FALSE);
1984 buffer_format->italic = (format_state->italics != FALSE);
1985 buffer_format->color = format_state->color;
1986 buffer_format->font_size = format_state->font_size;
1987 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1988 buffer_format->justification = format_state->justification;
1989 buffer_format->bullet = format_state->bullet;
1991 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1993 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1994 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1995 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1996 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1997 buffer_format->cs.font = (buffer_format->font != current_format->font);
1998 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1999 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
2001 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
2002 if (buffer_format->cs.bold) {
2003 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
2004 GINT_TO_POINTER (buffer_format->bold&0x1));
2006 if (buffer_format->cs.italic) {
2007 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
2008 GINT_TO_POINTER (buffer_format->italic&0x1));
2010 if (buffer_format->cs.color) {
2011 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2012 GINT_TO_POINTER (&(buffer_format->color)));
2014 if (buffer_format->cs.font_size) {
2015 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2016 GINT_TO_POINTER (buffer_format->font_size));
2018 if (buffer_format->cs.justification) {
2019 switch (buffer_format->justification) {
2020 case GTK_JUSTIFY_LEFT:
2021 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
2022 GINT_TO_POINTER(TRUE));
2024 case GTK_JUSTIFY_CENTER:
2025 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
2026 GINT_TO_POINTER(TRUE));
2028 case GTK_JUSTIFY_RIGHT:
2029 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
2030 GINT_TO_POINTER(TRUE));
2037 if (buffer_format->cs.font) {
2038 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2039 GINT_TO_POINTER (buffer_format->font));
2041 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
2042 if (buffer_format->cs.bullet) {
2043 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
2044 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
2046 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
2048 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
2050 g_free (buffer_format);
2051 g_free (current_format);
2053 /* Check dimming rules */
2054 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2055 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
2059 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
2061 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2063 ModestWindowPrivate *parent_priv;
2064 ModestMsgEditWindowPrivate *priv;
2066 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2067 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2069 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
2070 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu");
2071 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2072 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
2074 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatPlainTextMenu");
2075 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2076 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
2079 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2081 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2082 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
2084 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2085 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
2087 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
2088 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
2091 switch (buffer_format->justification)
2093 case GTK_JUSTIFY_LEFT:
2094 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2096 case GTK_JUSTIFY_CENTER:
2097 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2099 case GTK_JUSTIFY_RIGHT:
2100 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2107 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
2109 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
2110 G_CALLBACK (modest_msg_edit_window_color_button_change),
2112 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
2113 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
2114 G_CALLBACK (modest_msg_edit_window_color_button_change),
2117 if (priv->current_size_index != buffer_format->font_size) {
2121 path = gtk_tree_path_new_from_indices (buffer_format->font_size, -1);
2122 if (gtk_tree_model_get_iter (priv->sizes_model, &iter, path)) {
2126 priv->current_size_index = buffer_format->font_size;
2128 gtk_tree_model_get (priv->sizes_model, &iter, 0, &size_text, -1);
2129 markup = g_strconcat ("<span font_family='Sans'>",
2130 size_text, "</span>", NULL);
2132 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2136 gtk_tree_path_free (path);
2139 if (priv->current_face_index != buffer_format->font) {
2143 path = gtk_tree_path_new_from_indices (buffer_format->font, -1);
2144 if (gtk_tree_model_get_iter (priv->faces_model, &iter, path)) {
2148 priv->current_face_index = buffer_format->font;
2149 gtk_tree_model_get (priv->faces_model, &iter, 0, &face_name, -1);
2150 markup = g_strconcat ("<span font_family='", face_name, "'>Tt</span>", NULL);
2151 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2158 g_free (buffer_format);
2162 #ifdef MODEST_HILDON_VERSION_0
2164 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2167 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2168 ModestMsgEditWindowPrivate *priv;
2169 GtkWidget *dialog = NULL;
2171 GdkColor *new_color = NULL;
2173 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2174 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2176 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2177 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2178 g_free (buffer_format);
2180 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2181 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2182 if (new_color != NULL) {
2183 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2184 (gpointer) new_color);
2187 gtk_widget_destroy (dialog);
2192 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2195 ModestMsgEditWindowPrivate *priv;
2196 GtkWidget *dialog = NULL;
2198 GdkColor *old_color = NULL;
2199 const GdkColor *new_color = NULL;
2201 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2202 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2204 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2205 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2207 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2208 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2209 if (new_color != NULL)
2210 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2212 gtk_widget_destroy (dialog);
2218 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2221 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2222 ModestMsgEditWindowPrivate *priv;
2223 GtkWidget *dialog = NULL;
2225 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2226 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2228 dialog = hildon_color_chooser_new ();
2229 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2230 g_free (buffer_format);
2232 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2234 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2235 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2238 gtk_widget_destroy (dialog);
2243 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2246 ModestMsgEditWindowPrivate *priv;
2247 GtkWidget *dialog = NULL;
2248 GdkColor *old_color = NULL;
2250 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2251 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2253 dialog = hildon_color_chooser_new ();
2254 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2256 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2258 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2259 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2261 gtk_widget_destroy (dialog);
2264 #endif /*!MODEST_HILDON_VERSION_0*/
2269 create_stream_for_uri (const gchar* uri)
2274 TnyStream *result = NULL;
2276 GnomeVFSHandle *handle = NULL;
2277 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2278 if (test == GNOME_VFS_OK) {
2279 TnyStream *vfssstream = TNY_STREAM (tny_vfs_stream_new (handle));
2280 /* Streams over OBEX (Bluetooth) are not seekable but
2281 * we expect them to be (we might need to read them
2282 * several times). So if this is a Bluetooth URI just
2283 * read the whole file into memory (this is not a fast
2284 * protocol so we can assume that these files are not
2285 * going to be very big) */
2286 if ((g_ascii_strncasecmp (uri, "obex://", 7) == 0)||
2287 (g_ascii_strncasecmp (uri, "upnpav://", 9) == 0)) {
2288 TnyStream *memstream = tny_camel_mem_stream_new ();
2289 tny_stream_write_to_stream (vfssstream, memstream);
2290 g_object_unref (vfssstream);
2293 result = vfssstream;
2301 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2304 ModestMsgEditWindowPrivate *priv;
2305 GtkWidget *dialog = NULL;
2307 GSList *uris = NULL;
2308 GSList *uri_node = NULL;
2310 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2312 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2313 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2314 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2316 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2318 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2319 GTK_WINDOW (dialog), GTK_WINDOW (window));
2321 response = gtk_dialog_run (GTK_DIALOG (dialog));
2323 case GTK_RESPONSE_OK:
2325 gchar *current_folder;
2326 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2327 current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
2328 if (current_folder && current_folder != '\0') {
2330 modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_INSERT_IMAGE_PATH,
2331 current_folder, &err);
2333 g_debug ("Error storing latest used folder: %s", err->message);
2337 g_free (current_folder);
2343 gtk_widget_destroy (dialog);
2345 g_object_ref (window);
2346 /* The operation could take some time so allow the dialog to be closed */
2347 while (gtk_events_pending ())
2348 gtk_main_iteration ();
2350 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2352 GnomeVFSHandle *handle = NULL;
2353 GnomeVFSResult result;
2354 GtkTextIter position;
2355 GtkTextMark *insert_mark;
2357 uri = (const gchar *) uri_node->data;
2358 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2359 if (result == GNOME_VFS_OK) {
2361 GnomeVFSFileInfo *info;
2362 gchar *filename, *basename, *escaped_filename;
2363 TnyMimePart *mime_part;
2365 const gchar *mime_type = NULL;
2366 GnomeVFSURI *vfs_uri;
2367 guint64 stream_size;
2369 gnome_vfs_close (handle);
2370 vfs_uri = gnome_vfs_uri_new (uri);
2372 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2373 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2374 g_free (escaped_filename);
2375 gnome_vfs_uri_unref (vfs_uri);
2376 info = gnome_vfs_file_info_new ();
2378 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2379 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2381 mime_type = gnome_vfs_file_info_get_mime_type (info);
2383 mime_part = tny_platform_factory_new_mime_part
2384 (modest_runtime_get_platform_factory ());
2386 TnyStream *stream = create_stream_for_uri (uri);
2388 if (stream == NULL) {
2390 modest_platform_information_banner (NULL, NULL,
2391 _FM("sfil_ib_opening_not_allowed"));
2393 g_object_unref (mime_part);
2394 gnome_vfs_file_info_unref (info);
2398 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2400 content_id = g_strdup_printf ("%d", priv->next_cid);
2401 tny_mime_part_set_content_id (mime_part, content_id);
2402 g_free (content_id);
2405 basename = g_path_get_basename (filename);
2406 tny_mime_part_set_filename (mime_part, basename);
2409 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size, window);
2411 if (pixbuf != NULL) {
2412 priv->images_size += stream_size;
2413 priv->images_count ++;
2414 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2415 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2416 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position,
2417 tny_mime_part_get_content_id (mime_part), pixbuf);
2418 g_object_unref (pixbuf);
2420 tny_list_prepend (priv->images, (GObject *) mime_part);
2421 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2423 modest_platform_information_banner (NULL, NULL,
2424 _("mail_ib_file_operation_failed"));
2428 g_object_unref (mime_part);
2429 gnome_vfs_file_info_unref (info);
2433 g_object_unref (window);
2437 on_attach_file_response (GtkDialog *dialog,
2441 GSList *uris = NULL;
2443 GnomeVFSFileSize total_size, allowed_size;
2444 ModestMsgEditWindow *window;
2445 ModestMsgEditWindowPrivate *priv;
2450 case GTK_RESPONSE_OK:
2452 gchar *current_folder;
2454 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2455 current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
2456 if (current_folder && current_folder != '\0') {
2458 modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_ATTACH_FILE_PATH,
2459 current_folder, &err);
2461 g_debug ("Error storing latest used folder: %s", err->message);
2465 g_free (current_folder);
2472 window = MODEST_MSG_EDIT_WINDOW (user_data);
2473 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2475 /* allowed size is the maximum size - what's already there */
2476 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2477 &att_num, &att_size);
2478 allowed_size = MODEST_MAX_ATTACHMENT_SIZE - att_size;
2481 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2483 const gchar *uri = (const gchar *) uri_node->data;
2486 modest_msg_edit_window_attach_file_one (window, uri, allowed_size);
2488 if (total_size > allowed_size) {
2489 g_warning ("%s: total size: %u",
2490 __FUNCTION__, (unsigned int)total_size);
2493 allowed_size -= total_size;
2495 g_slist_foreach (uris, (GFunc) g_free, NULL);
2496 g_slist_free (uris);
2498 gtk_widget_destroy (GTK_WIDGET (dialog));
2502 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2504 GtkWidget *dialog = NULL;
2505 ModestMsgEditWindowPrivate *priv;
2508 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(window));
2510 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2512 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2515 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window),
2516 GTK_FILE_CHOOSER_ACTION_OPEN);
2517 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2518 conf_folder = modest_conf_get_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_ATTACH_FILE_PATH, NULL);
2519 if (conf_folder && conf_folder[0] != '\0') {
2520 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), conf_folder);
2523 /* Set the default folder to images folder */
2524 docs_folder = g_build_filename (g_getenv (MODEST_MAEMO_UTILS_MYDOCS_ENV),
2525 ".documents", NULL);
2526 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), docs_folder);
2527 g_free (docs_folder);
2529 g_free (conf_folder);
2530 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2531 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2532 GTK_WINDOW (dialog), GTK_WINDOW (window));
2534 /* Connect to response & show */
2535 g_signal_connect (dialog, "response",
2536 G_CALLBACK (on_attach_file_response), window);
2537 gtk_widget_show (dialog);
2542 modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window,
2544 GnomeVFSFileSize allowed_size)
2547 GnomeVFSHandle *handle = NULL;
2548 ModestMsgEditWindowPrivate *priv;
2549 GnomeVFSResult result;
2550 GnomeVFSFileSize size = 0;
2551 g_return_val_if_fail (window, 0);
2552 g_return_val_if_fail (uri, 0);
2554 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2556 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2557 if (result == GNOME_VFS_OK) {
2558 TnyMimePart *mime_part;
2560 const gchar *mime_type = NULL;
2562 gchar *escaped_filename;
2565 GnomeVFSFileInfo *info;
2566 GnomeVFSURI *vfs_uri;
2568 gnome_vfs_close (handle);
2569 vfs_uri = gnome_vfs_uri_new (uri);
2572 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2573 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2574 g_free (escaped_filename);
2575 gnome_vfs_uri_unref (vfs_uri);
2577 info = gnome_vfs_file_info_new ();
2579 if (gnome_vfs_get_file_info (uri,
2581 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2583 mime_type = gnome_vfs_file_info_get_mime_type (info);
2584 mime_part = tny_platform_factory_new_mime_part
2585 (modest_runtime_get_platform_factory ());
2587 /* try to get the attachment's size; this may fail for weird
2588 * file systems, like obex, upnp... */
2589 if (allowed_size != 0 &&
2590 info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
2592 if (size > allowed_size) {
2593 modest_platform_information_banner (NULL, NULL,
2594 _FM("sfil_ib_opening_not_allowed"));
2599 g_warning ("%s: could not get attachment size", __FUNCTION__);
2601 stream = create_stream_for_uri (uri);
2603 if (stream == NULL) {
2605 modest_platform_information_banner (NULL, NULL, _FM("sfil_ib_opening_not_allowed"));
2607 g_object_unref (mime_part);
2609 gnome_vfs_file_info_unref (info);
2613 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2614 g_object_unref (stream);
2616 content_id = g_strdup_printf ("%d", priv->next_cid);
2617 tny_mime_part_set_content_id (mime_part, content_id);
2618 g_free (content_id);
2621 basename = g_path_get_basename (filename);
2622 tny_mime_part_set_filename (mime_part, basename);
2625 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2626 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2628 info->size == 0, info->size);
2629 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2630 gtk_widget_show_all (priv->attachments_caption);
2631 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2633 g_object_unref (mime_part);
2634 gnome_vfs_file_info_unref (info);
2641 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2644 ModestMsgEditWindowPrivate *priv;
2647 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2648 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2650 if (att_list == NULL) {
2651 att_list = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2652 if (!modest_maemo_utils_select_attachments (GTK_WINDOW (window), att_list, TRUE)) {
2653 g_object_unref (att_list);
2658 g_object_ref (att_list);
2661 if (tny_list_get_length (att_list) == 0) {
2662 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2664 gboolean dialog_response;
2665 gchar *message = NULL;
2666 gchar *filename = NULL;
2668 if (tny_list_get_length (att_list) == 1) {
2670 iter = tny_list_create_iterator (att_list);
2671 part = (TnyMimePart *) tny_iterator_get_current (iter);
2672 g_object_unref (iter);
2673 if (TNY_IS_MSG (part)) {
2674 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2676 filename = tny_header_dup_subject (header);
2677 g_object_unref (header);
2679 if (filename == NULL) {
2680 filename = g_strdup (_("mail_va_no_subject"));
2683 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2685 g_object_unref (part);
2687 filename = g_strdup ("");
2689 message = g_strdup_printf (ngettext("emev_nc_delete_attachment",
2690 "emev_nc_delete_attachments",
2691 tny_list_get_length (att_list)), filename);
2694 dialog_response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
2698 if (dialog_response != GTK_RESPONSE_OK) {
2699 g_object_unref (att_list);
2703 for (iter = tny_list_create_iterator (att_list);
2704 !tny_iterator_is_done (iter);
2705 tny_iterator_next (iter)) {
2706 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2707 const gchar *att_id;
2708 tny_list_remove (priv->attachments, (GObject *) mime_part);
2710 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2712 if (tny_list_get_length (priv->attachments) == 0)
2713 gtk_widget_hide (priv->attachments_caption);
2714 att_id = tny_mime_part_get_content_id (mime_part);
2716 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2718 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2719 g_object_unref (mime_part);
2721 g_object_unref (iter);
2724 g_object_unref (att_list);
2726 /* if the last attachment has been removed, focus the Subject: field */
2727 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2728 gtk_widget_grab_focus (priv->subject_field);
2732 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2735 ModestMsgEditWindowPrivate *priv;
2736 GdkColor *new_color;
2737 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2739 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2740 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2743 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2745 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2747 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2749 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2754 font_size_clicked (GtkToolButton *button,
2755 ModestMsgEditWindow *window)
2757 ModestMsgEditWindowPrivate *priv;
2758 GtkWidget *selector, *dialog;
2760 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2762 selector = hildon_touch_selector_new ();
2763 hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector), priv->sizes_model, TRUE);
2764 hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, priv->current_size_index);
2766 dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
2767 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog), HILDON_TOUCH_SELECTOR (selector));
2768 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_font_size"));
2770 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2774 WPTextBufferFormat format;
2776 new_index = hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (selector), 0);
2778 memset (&format, 0, sizeof (format));
2779 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2781 format.cs.font_size = TRUE;
2782 format.cs.text_position = TRUE;
2783 format.cs.font = TRUE;
2784 format.font_size = new_index;
2785 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2787 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2788 GINT_TO_POINTER (new_index)))
2789 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2791 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2792 size_text = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector));
2793 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
2794 size_text, "</span>", NULL);
2796 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2800 gtk_widget_destroy (dialog);
2802 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2807 font_face_clicked (GtkToolButton *button,
2808 ModestMsgEditWindow *window)
2810 ModestMsgEditWindowPrivate *priv;
2811 GtkWidget *selector, *dialog;
2812 GtkCellRenderer *renderer;
2814 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2816 selector = hildon_touch_selector_new ();
2817 renderer = gtk_cell_renderer_text_new ();
2818 hildon_touch_selector_append_column (HILDON_TOUCH_SELECTOR (selector), priv->faces_model,
2819 renderer, "family", 0, "text", 0, NULL);
2820 hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, priv->current_face_index);
2822 dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
2823 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog), HILDON_TOUCH_SELECTOR (selector));
2824 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_font_face"));
2826 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2827 gint new_font_index;
2831 new_font_index = hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (selector), 0);
2832 path = gtk_tree_path_new_from_indices (new_font_index, -1);
2833 if (gtk_tree_model_get_iter (priv->faces_model, &iter, path)) {
2837 gtk_tree_model_get (priv->faces_model, &iter, 0, &face_name, -1);
2839 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2840 GINT_TO_POINTER(new_font_index)))
2841 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2843 markup = g_strconcat ("<span font_family='", face_name, "'>Tt</span>", NULL);
2844 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2846 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2850 gtk_tree_path_free (path);
2853 gtk_widget_destroy (dialog);
2855 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2860 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2863 ModestMsgEditWindowPrivate *priv = NULL;
2864 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2866 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2867 if (!priv->update_caption_visibility)
2870 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2872 gtk_widget_show (priv->cc_caption);
2874 gtk_widget_hide (priv->cc_caption);
2876 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2880 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2883 ModestMsgEditWindowPrivate *priv = NULL;
2884 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2886 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2887 if (!priv->update_caption_visibility)
2890 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2892 gtk_widget_show (priv->bcc_caption);
2894 gtk_widget_hide (priv->bcc_caption);
2896 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2900 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2901 ModestRecptEditor *editor)
2903 ModestMsgEditWindowPrivate *priv;
2905 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2906 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2908 /* we check for low-mem; in that case, show a warning, and don't allow
2909 * for the addressbook
2911 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2914 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2916 if (editor == NULL) {
2917 GtkWidget *view_focus;
2918 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2920 /* This code should be kept in sync with ModestRecptEditor. The
2921 textview inside the recpt editor is the one that really gets the
2922 focus. As it's inside a scrolled window, and this one inside the
2923 hbox recpt editor inherits from, we'll need to go up in the
2924 hierarchy to know if the text view is part of the recpt editor
2925 or if it's a different text entry */
2927 if (gtk_widget_get_parent (view_focus)) {
2928 GtkWidget *first_parent;
2930 first_parent = gtk_widget_get_parent (view_focus);
2931 if (gtk_widget_get_parent (first_parent) &&
2932 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2933 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2938 editor = MODEST_RECPT_EDITOR (priv->to_field);
2942 modest_address_book_select_addresses (editor);
2947 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2949 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2951 modest_msg_edit_window_open_addressbook (window, NULL);
2955 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2956 gboolean show_toolbar)
2958 ModestWindowPrivate *parent_priv;
2960 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2961 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2963 /* We can not just use the code of
2964 modest_msg_edit_window_setup_toolbar because it has a
2965 mixture of both initialization and creation code. */
2967 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2969 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2973 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2974 TnyHeaderFlags priority_flags)
2976 ModestMsgEditWindowPrivate *priv;
2977 ModestWindowPrivate *parent_priv;
2979 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2981 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2982 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2984 if (priv->priority_flags != priority_flags) {
2985 GtkAction *priority_action = NULL;
2987 priv->priority_flags = priority_flags;
2989 switch (priority_flags) {
2990 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2991 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2992 MODEST_HEADER_ICON_HIGH,
2993 HILDON_ICON_SIZE_SMALL);
2994 gtk_widget_show (priv->priority_icon);
2995 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2996 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2998 case TNY_HEADER_FLAG_LOW_PRIORITY:
2999 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
3000 MODEST_HEADER_ICON_LOW,
3001 HILDON_ICON_SIZE_SMALL);
3002 gtk_widget_show (priv->priority_icon);
3003 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
3004 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
3007 gtk_widget_hide (priv->priority_icon);
3008 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
3009 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
3012 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
3013 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3015 gtk_widget_queue_resize (priv->subject_box);
3019 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
3022 ModestMsgEditWindowPrivate *priv;
3023 ModestWindowPrivate *parent_priv;
3024 gint current_format;
3026 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3028 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3029 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3031 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
3032 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
3034 if (current_format != file_format) {
3035 switch (file_format) {
3036 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
3037 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
3038 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
3040 case MODEST_FILE_FORMAT_PLAIN_TEXT:
3044 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
3045 response = gtk_dialog_run (GTK_DIALOG (dialog));
3046 gtk_widget_destroy (dialog);
3047 if (response == GTK_RESPONSE_OK) {
3048 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
3050 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu"));
3051 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
3056 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3057 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3058 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
3063 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
3066 ModestMsgEditWindowPrivate *priv;
3067 WPTextBufferFormat oldfmt, fmt;
3068 gint old_position = 0;
3072 GdkColor *color = NULL;
3073 gboolean bold, bold_set, italic, italic_set;
3074 gboolean underline, underline_set;
3075 gboolean strikethrough, strikethrough_set;
3076 gboolean position_set;
3077 gboolean font_size_set, font_set, color_set;
3080 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3081 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3083 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
3084 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(),
3085 GTK_WINDOW(dialog), GTK_WINDOW (window));
3087 /* First we get the currently selected font information */
3088 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
3090 switch (oldfmt.text_position) {
3091 case TEXT_POSITION_NORMAL:
3094 case TEXT_POSITION_SUPERSCRIPT:
3102 g_object_set (G_OBJECT (dialog),
3103 "bold", oldfmt.bold != FALSE,
3104 "bold-set", !oldfmt.cs.bold,
3105 "underline", oldfmt.underline != FALSE,
3106 "underline-set", !oldfmt.cs.underline,
3107 "italic", oldfmt.italic != FALSE,
3108 "italic-set", !oldfmt.cs.italic,
3109 "strikethrough", oldfmt.strikethrough != FALSE,
3110 "strikethrough-set", !oldfmt.cs.strikethrough,
3111 "color", &oldfmt.color,
3112 "color-set", !oldfmt.cs.color,
3113 "size", wp_font_size[oldfmt.font_size],
3114 "size-set", !oldfmt.cs.font_size,
3115 "position", old_position,
3116 "position-set", !oldfmt.cs.text_position,
3117 "family", wp_get_font_name (oldfmt.font),
3118 "family-set", !oldfmt.cs.font,
3121 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
3122 GTK_WINDOW (dialog), GTK_WINDOW (window));
3123 gtk_widget_show_all (dialog);
3124 priv->font_dialog = dialog;
3125 response = gtk_dialog_run (GTK_DIALOG (dialog));
3126 priv->font_dialog = NULL;
3127 if (response == GTK_RESPONSE_OK) {
3129 g_object_get( dialog,
3131 "bold-set", &bold_set,
3132 "underline", &underline,
3133 "underline-set", &underline_set,
3135 "italic-set", &italic_set,
3136 "strikethrough", &strikethrough,
3137 "strikethrough-set", &strikethrough_set,
3139 "color-set", &color_set,
3141 "size-set", &font_size_set,
3142 "family", &font_name,
3143 "family-set", &font_set,
3144 "position", &position,
3145 "position-set", &position_set,
3150 if (response == GTK_RESPONSE_OK) {
3151 memset(&fmt, 0, sizeof(fmt));
3157 fmt.italic = italic;
3158 fmt.cs.italic = TRUE;
3160 if (underline_set) {
3161 fmt.underline = underline;
3162 fmt.cs.underline = TRUE;
3164 if (strikethrough_set) {
3165 fmt.strikethrough = strikethrough;
3166 fmt.cs.strikethrough = TRUE;
3171 ? TEXT_POSITION_NORMAL
3172 : ( ( position == 1 )
3173 ? TEXT_POSITION_SUPERSCRIPT
3174 : TEXT_POSITION_SUBSCRIPT );
3175 fmt.cs.text_position = TRUE;
3176 fmt.font_size = oldfmt.font_size;
3180 fmt.cs.color = TRUE;
3183 fmt.font = wp_get_font_index(font_name,
3188 if (font_size_set) {
3189 fmt.cs.font_size = TRUE;
3190 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
3192 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
3193 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
3195 gtk_widget_destroy (dialog);
3197 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
3201 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
3203 ModestMsgEditWindowPrivate *priv;
3205 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3206 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3208 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
3210 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3211 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3215 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
3217 ModestMsgEditWindowPrivate *priv;
3219 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3220 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3222 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
3224 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3225 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3230 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
3232 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3234 priv->can_undo = can_undo;
3238 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
3240 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3242 priv->can_redo = can_redo;
3246 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
3248 ModestMsgEditWindowPrivate *priv;
3249 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3250 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3252 return priv->can_undo;
3256 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
3258 ModestMsgEditWindowPrivate *priv;
3259 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3260 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3262 return priv->can_redo;
3267 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
3270 GtkTextIter match_start, match_end;
3272 if (image_id == NULL)
3275 gtk_text_buffer_get_start_iter (buffer, &iter);
3277 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
3278 GSList *tags = gtk_text_iter_get_tags (&match_start);
3280 for (node = tags; node != NULL; node = g_slist_next (node)) {
3281 GtkTextTag *tag = (GtkTextTag *) node->data;
3282 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
3283 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
3284 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
3286 offset = gtk_text_iter_get_offset (&match_start);
3287 gtk_text_buffer_delete (buffer, &match_start, &match_end);
3288 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
3292 gtk_text_iter_forward_char (&iter);
3297 message_is_empty (ModestMsgEditWindow *window)
3299 ModestMsgEditWindowPrivate *priv = NULL;
3301 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3302 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3304 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
3305 * so we can ignore markup.
3307 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
3310 count = gtk_text_buffer_get_char_count (buf);
3316 msg_body_focus (GtkWidget *focus,
3317 GdkEventFocus *event,
3321 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3322 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3323 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3328 recpt_field_changed (GtkTextBuffer *buffer,
3329 ModestMsgEditWindow *editor)
3331 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3332 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3336 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3338 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3339 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3343 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3346 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3347 GtkTextBuffer *buffer;
3349 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3350 gtk_text_buffer_set_modified (buffer, modified);
3351 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3352 gtk_text_buffer_set_modified (buffer, modified);
3353 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3354 gtk_text_buffer_set_modified (buffer, modified);
3355 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3359 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3361 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3362 const char *account_name;
3363 GtkTextBuffer *buffer;
3365 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3366 if (gtk_text_buffer_get_modified (buffer))
3368 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3369 if (gtk_text_buffer_get_modified (buffer))
3371 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3372 if (gtk_text_buffer_get_modified (buffer))
3374 if (gtk_text_buffer_get_modified (priv->text_buffer))
3377 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3378 if (priv->original_mailbox) {
3379 if (!account_name || strcmp (account_name, priv->original_mailbox))
3381 } else if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3392 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3394 ModestMsgEditWindowPrivate *priv = NULL;
3396 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3397 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3399 /* check if there's no recipient added */
3400 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3401 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3402 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3403 /* no recipient contents, then select contacts */
3404 modest_msg_edit_window_open_addressbook (window, NULL);
3408 g_object_ref (window);
3409 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3410 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3411 g_object_unref (window);
3414 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3415 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3416 g_object_unref (window);
3419 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3420 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3421 g_object_unref (window);
3425 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3426 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3427 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3428 g_object_unref (window);
3435 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3436 ModestMsgEditWindow *window)
3438 modest_msg_edit_window_offer_attach_file (window);
3442 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3444 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3446 return priv->clipboard_text;
3450 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3452 ModestMsgEditWindow *window)
3454 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3455 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3458 /* It could happen that the window was already closed */
3459 if (!GTK_WIDGET_VISIBLE (window))
3462 g_object_ref (window);
3463 text = gtk_clipboard_wait_for_text (selection_clipboard);
3465 if (priv->clipboard_text != NULL) {
3466 g_free (priv->clipboard_text);
3468 priv->clipboard_text = text;
3470 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3472 g_object_unref (window);
3475 static gboolean clipboard_owner_change_idle (gpointer userdata)
3477 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
3478 ModestMsgEditWindowPrivate *priv;
3480 gdk_threads_enter ();
3481 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3482 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3484 priv->clipboard_owner_idle = 0;
3485 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, window);
3486 gdk_threads_leave ();
3492 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window)
3494 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3495 if (priv->clipboard_owner_idle == 0) {
3496 priv->clipboard_owner_idle = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
3497 clipboard_owner_change_idle,
3498 g_object_ref (window),
3504 subject_field_move_cursor (GtkEntry *entry,
3505 GtkMovementStep step,
3510 /* It could happen that the window was already closed */
3511 if (!GTK_WIDGET_VISIBLE (window))
3514 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3518 update_window_title (ModestMsgEditWindow *window)
3520 ModestMsgEditWindowPrivate *priv = NULL;
3521 const gchar *subject;
3523 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3524 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3525 if (subject == NULL || subject[0] == '\0')
3526 subject = _("mail_va_new_email");
3528 gtk_window_set_title (GTK_WINDOW (window), subject);
3533 subject_field_changed (GtkEditable *editable,
3534 ModestMsgEditWindow *window)
3536 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3537 update_window_title (window);
3538 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3539 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3540 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3544 subject_field_insert_text (GtkEditable *editable,
3546 gint new_text_length,
3548 ModestMsgEditWindow *window)
3550 GString *result = g_string_new ("");
3552 gint result_len = 0;
3553 const gchar *entry_text = NULL;
3556 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3557 old_length = g_utf8_strlen (entry_text, -1);
3559 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3560 gunichar c = g_utf8_get_char_validated (current, 8);
3561 /* Invalid unichar, stop */
3567 result = g_string_append_unichar (result, c);
3571 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3572 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3575 /* Prevent endless recursion */
3576 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3577 g_signal_emit_by_name (editable, "insert-text",
3578 (gpointer) result->str, (gpointer) result->len,
3579 (gpointer) position, (gpointer) window);
3580 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3584 if (result_len + old_length > 1000) {
3585 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3586 _CS("ckdg_ib_maximum_characters_reached"));
3588 g_string_free (result, TRUE);
3592 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3595 ModestMsgEditWindowPrivate *priv = NULL;
3597 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3598 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3600 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3603 gtk_widget_show_all (priv->find_toolbar);
3604 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3606 gtk_widget_hide_all (priv->find_toolbar);
3607 gtk_widget_grab_focus (priv->msg_body);
3612 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3614 GtkTextIter *match_start,
3615 GtkTextIter *match_end)
3617 GtkTextIter end_iter;
3618 gchar *str_casefold;
3621 gchar *range_casefold;
3624 gboolean result = FALSE;
3631 gtk_text_iter_forward_to_end (&end_iter);
3633 str_casefold = g_utf8_casefold (str, -1);
3634 str_chars_n = strlen (str);
3636 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3637 range_casefold = g_utf8_casefold (range_text, -1);
3638 range_chars_n = strlen (range_casefold);
3640 if (range_chars_n < str_chars_n) {
3641 g_free (str_casefold);
3642 g_free (range_text);
3643 g_free (range_casefold);
3647 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3648 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3649 if (!g_utf8_collate (range_subtext, str_casefold)) {
3650 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3652 if (!gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3653 match_start, match_end, NULL)) {
3654 g_warning ("Matched string with collate, but not matched in model");
3656 g_free (found_text);
3658 g_free (range_subtext);
3662 g_free (str_casefold);
3663 g_free (range_text);
3664 g_free (range_casefold);
3671 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3672 ModestMsgEditWindow *window)
3674 gchar *current_search = NULL;
3675 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3677 GtkTextIter selection_start, selection_end;
3678 GtkTextIter match_start, match_end;
3679 gboolean continue_search = FALSE;
3681 if (message_is_empty (window)) {
3682 g_free (priv->last_search);
3683 priv->last_search = NULL;
3684 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3688 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3689 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3690 g_free (current_search);
3691 g_free (priv->last_search);
3692 priv->last_search = NULL;
3693 /* Information banner about empty search */
3694 hildon_banner_show_information (NULL, NULL, _CS("ecdg_ib_find_rep_enter_text"));
3698 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3699 continue_search = TRUE;
3701 g_free (priv->last_search);
3702 priv->last_search = g_strdup (current_search);
3705 if (continue_search) {
3706 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3707 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3708 &match_start, &match_end);
3710 hildon_banner_show_information (NULL, NULL, _HL("ckct_ib_find_search_complete"));
3712 GtkTextIter buffer_start;
3713 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3714 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3715 &match_start, &match_end);
3717 hildon_banner_show_information (NULL, NULL, _HL("ckct_ib_find_no_matches"));
3720 /* Mark as selected the string found in search */
3722 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3723 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3724 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3726 g_free (priv->last_search);
3727 priv->last_search = NULL;
3729 g_free (current_search);
3733 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3735 ModestMsgEditWindowPrivate *priv;
3737 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3742 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3745 ModestMsgEditWindowPrivate *priv;
3747 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3752 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3753 ModestMsgEditWindow *window)
3755 modest_msg_edit_window_toggle_find_toolbar (window, FALSE);
3759 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3762 ModestMsgEditWindowPrivate *priv;
3763 TnyHeader *header = NULL;
3765 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3766 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3768 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3770 if (priv->draft_msg != NULL) {
3771 g_object_unref (priv->draft_msg);
3774 if (draft != NULL) {
3775 g_object_ref (draft);
3776 header = tny_msg_get_header (draft);
3777 if (priv->msg_uid) {
3778 g_free (priv->msg_uid);
3779 priv->msg_uid = NULL;
3781 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3784 priv->draft_msg = draft;
3788 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3789 GtkTextIter *start, GtkTextIter *end,
3792 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3793 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3796 if (tag == NULL) return;
3797 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3798 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3799 replace_with_images (window, priv->images);
3804 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3807 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3809 g_return_if_fail (TNY_IS_MIME_PART (part));
3810 tny_list_prepend (priv->attachments, (GObject *) part);
3811 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3812 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3813 gtk_widget_show_all (priv->attachments_caption);
3814 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3818 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3820 ModestMsgEditWindowPrivate *priv;
3822 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3823 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3825 return priv->msg_uid;
3829 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3830 ModestMsgEditWindowWidgetType widget_type)
3832 ModestMsgEditWindowPrivate *priv;
3834 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3835 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3837 switch (widget_type) {
3838 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3839 return priv->msg_body;
3841 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3842 return priv->to_field;
3844 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3845 return priv->cc_field;
3847 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3848 return priv->bcc_field;
3850 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3851 return priv->subject_field;
3853 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3854 return priv->attachments_view;
3862 remove_tags (WPTextBuffer *buffer)
3864 GtkTextIter start, end;
3866 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3867 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3869 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3873 on_account_removed (TnyAccountStore *account_store,
3874 TnyAccount *account,
3877 /* Do nothing if it's a store account, because we use the
3878 transport to send the messages */
3879 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3880 const gchar *parent_acc = NULL;
3881 const gchar *our_acc = NULL;
3883 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3884 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3885 /* Close this window if I'm showing a message of the removed account */
3886 if (strcmp (parent_acc, our_acc) == 0)
3887 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3892 get_signature (const gchar *current_recipient, gboolean *has_signature)
3894 gchar *result = NULL;
3895 gchar *mailbox = NULL;
3896 gchar *account_name;
3897 ModestProtocol *protocol = NULL;
3899 *has_signature = FALSE;
3901 account_name = modest_utils_get_account_name_from_recipient (current_recipient, &mailbox);
3902 if (account_is_multimailbox (account_name, &protocol)
3904 if (MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
3905 result = modest_account_protocol_get_signature (MODEST_ACCOUNT_PROTOCOL (protocol),
3906 account_name, mailbox,
3911 if (result == NULL) {
3912 result = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (),
3913 account_name, has_signature);
3918 static void update_signature (ModestMsgEditWindow *self,
3919 const gchar *old_account,
3920 const gchar *new_account)
3922 ModestMsgEditWindowPrivate *priv;
3923 gboolean has_old_signature, has_new_signature;
3925 GtkTextIter match_start, match_end;
3926 ModestAccountMgr *mgr;
3928 gchar *full_signature;
3930 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
3932 gtk_text_buffer_begin_user_action (priv->text_buffer);
3934 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
3935 mgr = modest_runtime_get_account_mgr ();
3939 signature = get_signature (old_account, &has_old_signature);
3940 if (has_old_signature) {
3941 full_signature = g_strconcat ("\n--\n", signature, NULL);
3942 if (gtk_text_iter_forward_search (&iter, full_signature, 0, &match_start, &match_end, NULL)) {
3943 gtk_text_buffer_delete (priv->text_buffer, &match_start, &match_end);
3945 } else if (gtk_text_iter_forward_search (&iter, _("mcen_ia_editor_original_message"), 0,
3946 &match_start, &match_end, NULL)) {
3949 g_free (full_signature);
3954 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3955 signature = get_signature (new_account, &has_new_signature);
3956 if (has_new_signature) {
3957 full_signature = g_strconcat ("\n--\n", signature, NULL);
3958 gtk_text_buffer_insert (priv->text_buffer, &iter, full_signature, -1);
3959 g_free (full_signature);
3962 gtk_text_buffer_end_user_action (priv->text_buffer);
3966 from_field_changed (HildonPickerButton *button,
3967 ModestMsgEditWindow *self)
3969 ModestMsgEditWindowPrivate *priv;
3970 gchar *old_account, *new_account;
3972 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
3974 old_account = priv->last_from_account;
3975 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3976 new_account = priv->last_from_account;
3978 update_signature (self, old_account, new_account);
3982 typedef struct _MessageSettingsHelper {
3983 ModestMsgEditWindow *window;
3984 GSList *priority_group;
3985 GSList *format_group;
3986 GtkToggleButton *current_priority;
3987 GtkToggleButton *current_format;
3988 } MessageSettingsHelper;
3991 on_priority_toggle (GtkToggleButton *button,
3992 MessageSettingsHelper *helper)
3995 ModestMsgEditWindowPrivate *priv;
3997 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (helper->window);
3998 if (gtk_toggle_button_get_active (button)) {
4000 for (node = helper->priority_group; node != NULL; node = g_slist_next (node)) {
4001 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
4002 if ((node_button != button) &&
4003 gtk_toggle_button_get_active (node_button)) {
4004 gtk_toggle_button_set_active (node_button, FALSE);
4007 helper->current_priority = button;
4009 gboolean found = FALSE;
4010 /* If no one is active, activate it again */
4011 for (node = helper->priority_group; node != NULL; node = g_slist_next (node)) {
4012 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
4013 if (gtk_toggle_button_get_active (node_button)) {
4019 gtk_toggle_button_set_active (button, TRUE);
4025 on_format_toggle (GtkToggleButton *button,
4026 MessageSettingsHelper *helper)
4029 ModestMsgEditWindowPrivate *priv;
4031 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (helper->window);
4032 if (gtk_toggle_button_get_active (button)) {
4034 for (node = helper->format_group; node != NULL; node = g_slist_next (node)) {
4035 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
4036 if ((node_button != button) &&
4037 gtk_toggle_button_get_active (node_button)) {
4038 gtk_toggle_button_set_active (node_button, FALSE);
4041 helper->current_format = button;
4043 gboolean found = FALSE;
4044 /* If no one is active, activate it again */
4045 for (node = helper->format_group; node != NULL; node = g_slist_next (node)) {
4046 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
4047 if (gtk_toggle_button_get_active (node_button)) {
4053 gtk_toggle_button_set_active (button, TRUE);
4060 modest_msg_edit_window_show_msg_settings_dialog (ModestMsgEditWindow *window)
4065 GtkWidget *priority_hbox;
4066 GtkWidget *high_toggle, *medium_toggle, *low_toggle;
4067 GtkWidget *captioned;
4068 GtkSizeGroup *title_sizegroup, *value_sizegroup;
4069 GtkWidget *format_hbox;
4070 GtkWidget *html_toggle, *text_toggle;
4071 ModestMsgEditWindowPrivate *priv;
4072 MessageSettingsHelper helper = {0,};
4074 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4075 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
4076 helper.window = window;
4077 helper.priority_group = NULL;
4078 helper.format_group = NULL;
4080 title_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4081 value_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4083 dialog = gtk_dialog_new_with_buttons (_("mcen_me_message_settings"), NULL,
4084 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
4085 _HL("wdgt_bd_done"), GTK_RESPONSE_ACCEPT, NULL);
4086 vbox = gtk_vbox_new (FALSE, 0);
4087 align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
4088 gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE, 0);
4089 gtk_container_add (GTK_CONTAINER (align), vbox);
4090 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), align);
4091 gtk_widget_show (align);
4092 gtk_widget_show (vbox);
4094 /* Priority toggles */
4095 priority_hbox = gtk_hbox_new (TRUE, 0);
4096 high_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4097 gtk_button_set_label (GTK_BUTTON (high_toggle), _("mcen_me_editor_priority_high"));
4098 helper.priority_group = g_slist_prepend (helper.priority_group, high_toggle);
4099 g_object_set_data (G_OBJECT (high_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_HIGH_PRIORITY));
4100 medium_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4101 gtk_button_set_label (GTK_BUTTON (medium_toggle), _("mcen_me_editor_priority_normal"));
4102 helper.priority_group = g_slist_prepend (helper.priority_group, medium_toggle);
4103 g_object_set_data (G_OBJECT (medium_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_NORMAL_PRIORITY));
4104 low_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4105 gtk_button_set_label (GTK_BUTTON (low_toggle), _("mcen_me_editor_priority_low"));
4106 helper.priority_group = g_slist_prepend (helper.priority_group, low_toggle);
4107 g_object_set_data (G_OBJECT (low_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_LOW_PRIORITY));
4108 gtk_box_pack_start (GTK_BOX (priority_hbox), low_toggle, TRUE, TRUE, 0);
4109 gtk_box_pack_start (GTK_BOX (priority_hbox), medium_toggle, TRUE, TRUE, 0);
4110 gtk_box_pack_start (GTK_BOX (priority_hbox), high_toggle, TRUE, TRUE, 0);
4111 gtk_widget_show_all (priority_hbox);
4112 captioned = modest_maemo_utils_create_captioned (title_sizegroup, value_sizegroup,
4113 _("mcen_me_editor_message_priority"), FALSE, priority_hbox);
4114 gtk_widget_show (captioned);
4115 gtk_box_pack_start (GTK_BOX (vbox), captioned, FALSE, FALSE, 0);
4117 /* format toggles */
4118 format_hbox = gtk_hbox_new (TRUE, 0);
4119 html_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4120 gtk_button_set_label (GTK_BUTTON (html_toggle), _("mcen_me_editor_formatted_text"));
4121 helper.format_group = g_slist_prepend (helper.format_group, html_toggle);
4122 g_object_set_data (G_OBJECT (html_toggle), "format", GINT_TO_POINTER (MODEST_MSG_EDIT_FORMAT_HTML));
4123 g_object_set_data (G_OBJECT (html_toggle), "file-format", GINT_TO_POINTER (MODEST_FILE_FORMAT_FORMATTED_TEXT));
4124 text_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4125 gtk_button_set_label (GTK_BUTTON (text_toggle), _("mcen_me_editor_plain_text"));
4126 helper.format_group = g_slist_prepend (helper.format_group, text_toggle);
4127 g_object_set_data (G_OBJECT (text_toggle), "format", GINT_TO_POINTER (MODEST_MSG_EDIT_FORMAT_TEXT));
4128 g_object_set_data (G_OBJECT (text_toggle), "file-format", GINT_TO_POINTER (MODEST_FILE_FORMAT_PLAIN_TEXT));
4129 gtk_box_pack_start (GTK_BOX (format_hbox), html_toggle, TRUE, TRUE, 0);
4130 gtk_box_pack_start (GTK_BOX (format_hbox), text_toggle, TRUE, TRUE, 0);
4131 gtk_widget_show_all (format_hbox);
4132 gtk_widget_show (format_hbox);
4133 gtk_box_pack_start (GTK_BOX (vbox), format_hbox, FALSE, FALSE, 0);
4136 g_object_unref (title_sizegroup);
4137 g_object_unref (value_sizegroup);
4139 /* Set current values */
4140 switch (priv->priority_flags) {
4141 case TNY_HEADER_FLAG_HIGH_PRIORITY:
4142 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (high_toggle), TRUE);
4143 helper.current_priority = GTK_TOGGLE_BUTTON (high_toggle);
4145 case TNY_HEADER_FLAG_LOW_PRIORITY:
4146 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (low_toggle), TRUE);
4147 helper.current_priority = GTK_TOGGLE_BUTTON (low_toggle);
4150 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (medium_toggle), TRUE);
4151 helper.current_priority = GTK_TOGGLE_BUTTON (medium_toggle);
4155 switch (modest_msg_edit_window_get_format (window)) {
4156 case MODEST_MSG_EDIT_FORMAT_TEXT:
4157 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (text_toggle), TRUE);
4158 helper.current_format = GTK_TOGGLE_BUTTON (text_toggle);
4160 case MODEST_MSG_EDIT_FORMAT_HTML:
4162 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (html_toggle), TRUE);
4163 helper.current_format = GTK_TOGGLE_BUTTON (html_toggle);
4167 /* Signal connects */
4168 g_signal_connect (G_OBJECT (high_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4169 g_signal_connect (G_OBJECT (medium_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4170 g_signal_connect (G_OBJECT (low_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4171 g_signal_connect (G_OBJECT (html_toggle), "toggled", G_CALLBACK (on_format_toggle), &helper);
4172 g_signal_connect (G_OBJECT (text_toggle), "toggled", G_CALLBACK (on_format_toggle), &helper);
4174 /* Save settings if the user clicked on done */
4175 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
4176 TnyHeaderFlags flags;
4177 ModestMsgEditFormat old_format, new_format;
4179 /* Set priority flags */
4180 flags = (TnyHeaderFlags) g_object_get_data (G_OBJECT (helper.current_priority), "priority");
4181 if (priv->priority_flags != flags)
4182 modest_msg_edit_window_set_priority_flags (window, flags);
4184 /* Set edit format */
4185 old_format = modest_msg_edit_window_get_format (window);
4186 new_format = (ModestMsgEditFormat) g_object_get_data (G_OBJECT (helper.current_format), "format");
4187 if (old_format != new_format) {
4188 gint file_format = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (helper.current_format), "file-format"));
4189 modest_msg_edit_window_set_file_format (window, file_format);
4193 gtk_widget_destroy (dialog);
4194 g_slist_free (helper.priority_group);
4198 on_message_settings (GtkAction *action,
4199 ModestMsgEditWindow *window)
4201 modest_msg_edit_window_show_msg_settings_dialog (window);
4205 on_cc_button_toggled (HildonCheckButton *button,
4206 ModestMsgEditWindow *window)
4208 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
4210 modest_msg_edit_window_show_cc (MODEST_MSG_EDIT_WINDOW (window),
4211 hildon_check_button_get_active (button));
4215 on_bcc_button_toggled (HildonCheckButton *button,
4216 ModestMsgEditWindow *window)
4218 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
4220 modest_msg_edit_window_show_bcc (MODEST_MSG_EDIT_WINDOW (window),
4221 hildon_check_button_get_active (button));
4225 setup_menu (ModestMsgEditWindow *self)
4227 ModestMsgEditWindowPrivate *priv = NULL;
4229 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(self));
4231 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
4233 /* Settings menu buttons */
4234 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_editor_checknames"), NULL,
4235 APP_MENU_CALLBACK (modest_ui_actions_on_check_names),
4237 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_undo"), "<Ctrl>z",
4238 APP_MENU_CALLBACK (modest_ui_actions_on_undo),
4239 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_undo));
4241 priv->cc_button = hildon_check_button_new (0);
4242 gtk_button_set_label (GTK_BUTTON (priv->cc_button), _("mcen_me_editor_showcc"));
4243 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->cc_button),
4245 modest_hildon2_window_add_button_to_menu (MODEST_HILDON2_WINDOW (self), GTK_BUTTON (priv->cc_button),
4247 g_signal_connect (G_OBJECT (priv->cc_button), "toggled",
4248 G_CALLBACK (on_cc_button_toggled), (gpointer) self);
4249 priv->bcc_button = hildon_check_button_new (0);
4250 gtk_button_set_label (GTK_BUTTON (priv->bcc_button), _("mcen_me_editor_showbcc"));
4251 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->bcc_button),
4253 modest_hildon2_window_add_button_to_menu (MODEST_HILDON2_WINDOW (self), GTK_BUTTON (priv->bcc_button),
4255 g_signal_connect (G_OBJECT (priv->bcc_button), "toggled",
4256 G_CALLBACK (on_bcc_button_toggled), (gpointer) self);
4258 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_editor_attach_inlineimage"), NULL,
4259 APP_MENU_CALLBACK (modest_ui_actions_on_insert_image),
4260 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_set_style));
4261 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_remove_attachments"), NULL,
4262 APP_MENU_CALLBACK (modest_ui_actions_on_remove_attachments),
4263 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_editor_remove_attachment));
4264 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_message_settings"), NULL,
4265 APP_MENU_CALLBACK (on_message_settings),
4267 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_viewer_find"), "<Ctrl>f",
4268 APP_MENU_CALLBACK (modest_ui_actions_on_toggle_find_in_page),