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);
1685 update_signature (MODEST_MSG_EDIT_WINDOW (obj), account_name, priv->last_from_account);
1687 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1689 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1690 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1691 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1692 priv->update_caption_visibility = TRUE;
1694 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1696 /* Track account-removed signal, this window should be closed
1697 in the case we're creating a mail associated to the account
1699 priv->account_removed_handler_id =
1700 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1702 G_CALLBACK(on_account_removed),
1705 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (MODEST_MSG_EDIT_WINDOW (obj));
1707 return (ModestWindow*) obj;
1711 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1713 GString **string_buffer = (GString **) user_data;
1715 *string_buffer = g_string_append (*string_buffer, buffer);
1721 * @result: A new string which should be freed with g_free().
1724 get_formatted_data (ModestMsgEditWindow *edit_window)
1726 ModestMsgEditWindowPrivate *priv;
1727 GString *string_buffer = g_string_new ("");
1729 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1731 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1733 modest_text_utils_hyperlinkify (string_buffer);
1735 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1737 return g_string_free (string_buffer, FALSE);
1742 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1745 const gchar *account_name;
1746 ModestMsgEditWindowPrivate *priv;
1747 TnyIterator *att_iter;
1748 const gchar *picker_active_id;
1750 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1752 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1754 picker_active_id = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1755 g_return_val_if_fail (picker_active_id, NULL);
1756 account_name = modest_utils_get_account_name_from_recipient (picker_active_id, NULL);
1758 /* don't free these (except from) */
1759 data = g_slice_new0 (MsgData);
1760 data->from = g_strdup ((gchar *) modest_selector_picker_get_active_display_name (MODEST_SELECTOR_PICKER (priv->from_field)));
1761 data->account_name = g_strdup (account_name);
1762 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1763 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1764 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1765 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1766 data->references = g_strdup (priv->references);
1767 data->in_reply_to = g_strdup (priv->in_reply_to);
1768 if (priv->draft_msg) {
1769 data->draft_msg = g_object_ref (priv->draft_msg);
1770 } else if (priv->outbox_msg) {
1771 data->draft_msg = g_object_ref (priv->outbox_msg);
1773 data->draft_msg = NULL;
1776 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1778 gtk_text_buffer_get_bounds (buf, &b, &e);
1779 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1781 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1782 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1784 data->html_body = NULL;
1786 /* deep-copy the data */
1787 att_iter = tny_list_create_iterator (priv->attachments);
1788 data->attachments = NULL;
1789 while (!tny_iterator_is_done (att_iter)) {
1790 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1791 if (!(TNY_IS_MIME_PART(part))) {
1792 g_warning ("strange data in attachment list");
1793 g_object_unref (part);
1794 tny_iterator_next (att_iter);
1797 data->attachments = g_list_append (data->attachments,
1799 tny_iterator_next (att_iter);
1801 g_object_unref (att_iter);
1803 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1804 att_iter = tny_list_create_iterator (priv->images);
1805 data->images = NULL;
1806 while (!tny_iterator_is_done (att_iter)) {
1807 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1809 if (!(TNY_IS_MIME_PART(part))) {
1810 g_warning ("strange data in attachment list");
1811 g_object_unref (part);
1812 tny_iterator_next (att_iter);
1815 cid = tny_mime_part_get_content_id (part);
1817 gchar *image_tag_id;
1818 GtkTextTag *image_tag;
1820 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1821 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1822 g_free (image_tag_id);
1824 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1826 ((gtk_text_iter_has_tag (&iter, image_tag))||
1827 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1828 data->images = g_list_append (data->images,
1829 g_object_ref (part));
1831 g_object_unref (part);
1832 tny_iterator_next (att_iter);
1834 g_object_unref (att_iter);
1836 data->priority_flags = priv->priority_flags;
1843 unref_gobject (GObject *obj, gpointer data)
1845 if (!G_IS_OBJECT(obj))
1847 g_object_unref (obj);
1851 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1854 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1862 g_free (data->from);
1863 g_free (data->subject);
1864 g_free (data->plain_body);
1865 g_free (data->html_body);
1866 g_free (data->account_name);
1867 g_free (data->references);
1868 g_free (data->in_reply_to);
1870 if (data->draft_msg != NULL) {
1871 g_object_unref (data->draft_msg);
1872 data->draft_msg = NULL;
1875 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1876 g_list_free (data->attachments);
1877 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1878 g_list_free (data->images);
1880 g_slice_free (MsgData, data);
1884 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1886 guint64 *parts_size)
1888 ModestMsgEditWindowPrivate *priv;
1890 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1892 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1894 /* TODO: add images */
1895 *parts_size += priv->images_size;
1896 *parts_count += priv->images_count;
1901 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1904 ModestMsgEditWindowPrivate *priv = NULL;
1905 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1907 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1909 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1911 return MODEST_MSG_EDIT_FORMAT_HTML;
1913 return MODEST_MSG_EDIT_FORMAT_TEXT;
1917 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1918 ModestMsgEditFormat format)
1920 ModestMsgEditWindowPrivate *priv;
1922 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1923 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1926 case MODEST_MSG_EDIT_FORMAT_HTML:
1927 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1929 case MODEST_MSG_EDIT_FORMAT_TEXT:
1930 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1933 g_return_if_reached ();
1937 ModestMsgEditFormatState *
1938 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1940 ModestMsgEditFormatState *format_state = NULL;
1941 ModestMsgEditWindowPrivate *priv;
1942 WPTextBufferFormat *buffer_format;
1944 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1946 buffer_format = g_new0 (WPTextBufferFormat, 1);
1947 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1949 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1951 format_state = g_new0 (ModestMsgEditFormatState, 1);
1952 format_state->bold = buffer_format->bold&0x1;
1953 format_state->italics = buffer_format->italic&0x1;
1954 format_state->bullet = buffer_format->bullet&0x1;
1955 format_state->color = buffer_format->color;
1956 format_state->font_size = buffer_format->font_size;
1957 format_state->font_family = wp_get_font_name (buffer_format->font);
1958 format_state->justification = buffer_format->justification;
1959 g_free (buffer_format);
1961 return format_state;
1966 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1967 const ModestMsgEditFormatState *format_state)
1969 ModestMsgEditWindowPrivate *priv;
1970 WPTextBufferFormat *buffer_format;
1971 WPTextBufferFormat *current_format;
1973 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1974 g_return_if_fail (format_state != NULL);
1976 buffer_format = g_new0 (WPTextBufferFormat, 1);
1977 current_format = g_new0 (WPTextBufferFormat, 1);
1979 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1980 gtk_widget_grab_focus (priv->msg_body);
1981 buffer_format->bold = (format_state->bold != FALSE);
1982 buffer_format->italic = (format_state->italics != FALSE);
1983 buffer_format->color = format_state->color;
1984 buffer_format->font_size = format_state->font_size;
1985 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1986 buffer_format->justification = format_state->justification;
1987 buffer_format->bullet = format_state->bullet;
1989 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1991 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1992 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1993 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1994 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1995 buffer_format->cs.font = (buffer_format->font != current_format->font);
1996 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1997 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1999 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
2000 if (buffer_format->cs.bold) {
2001 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
2002 GINT_TO_POINTER (buffer_format->bold&0x1));
2004 if (buffer_format->cs.italic) {
2005 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
2006 GINT_TO_POINTER (buffer_format->italic&0x1));
2008 if (buffer_format->cs.color) {
2009 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2010 GINT_TO_POINTER (&(buffer_format->color)));
2012 if (buffer_format->cs.font_size) {
2013 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2014 GINT_TO_POINTER (buffer_format->font_size));
2016 if (buffer_format->cs.justification) {
2017 switch (buffer_format->justification) {
2018 case GTK_JUSTIFY_LEFT:
2019 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
2020 GINT_TO_POINTER(TRUE));
2022 case GTK_JUSTIFY_CENTER:
2023 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
2024 GINT_TO_POINTER(TRUE));
2026 case GTK_JUSTIFY_RIGHT:
2027 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
2028 GINT_TO_POINTER(TRUE));
2035 if (buffer_format->cs.font) {
2036 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2037 GINT_TO_POINTER (buffer_format->font));
2039 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
2040 if (buffer_format->cs.bullet) {
2041 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
2042 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
2044 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
2046 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
2048 g_free (buffer_format);
2049 g_free (current_format);
2051 /* Check dimming rules */
2052 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2053 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
2057 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
2059 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2061 ModestWindowPrivate *parent_priv;
2062 ModestMsgEditWindowPrivate *priv;
2064 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2065 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2067 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
2068 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu");
2069 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2070 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
2072 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatPlainTextMenu");
2073 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2074 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
2077 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2079 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2080 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
2082 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2083 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
2085 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
2086 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
2089 switch (buffer_format->justification)
2091 case GTK_JUSTIFY_LEFT:
2092 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2094 case GTK_JUSTIFY_CENTER:
2095 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2097 case GTK_JUSTIFY_RIGHT:
2098 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2105 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
2107 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
2108 G_CALLBACK (modest_msg_edit_window_color_button_change),
2110 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
2111 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
2112 G_CALLBACK (modest_msg_edit_window_color_button_change),
2115 if (priv->current_size_index != buffer_format->font_size) {
2119 path = gtk_tree_path_new_from_indices (buffer_format->font_size, -1);
2120 if (gtk_tree_model_get_iter (priv->sizes_model, &iter, path)) {
2124 priv->current_size_index = buffer_format->font_size;
2126 gtk_tree_model_get (priv->sizes_model, &iter, 0, &size_text, -1);
2127 markup = g_strconcat ("<span font_family='Sans'>",
2128 size_text, "</span>", NULL);
2130 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2134 gtk_tree_path_free (path);
2137 if (priv->current_face_index != buffer_format->font) {
2141 path = gtk_tree_path_new_from_indices (buffer_format->font, -1);
2142 if (gtk_tree_model_get_iter (priv->faces_model, &iter, path)) {
2146 priv->current_face_index = buffer_format->font;
2147 gtk_tree_model_get (priv->faces_model, &iter, 0, &face_name, -1);
2148 markup = g_strconcat ("<span font_family='", face_name, "'>Tt</span>", NULL);
2149 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2156 g_free (buffer_format);
2160 #ifdef MODEST_HILDON_VERSION_0
2162 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2165 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2166 ModestMsgEditWindowPrivate *priv;
2167 GtkWidget *dialog = NULL;
2169 GdkColor *new_color = NULL;
2171 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2172 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2174 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2175 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2176 g_free (buffer_format);
2178 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2179 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2180 if (new_color != NULL) {
2181 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2182 (gpointer) new_color);
2185 gtk_widget_destroy (dialog);
2190 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2193 ModestMsgEditWindowPrivate *priv;
2194 GtkWidget *dialog = NULL;
2196 GdkColor *old_color = NULL;
2197 const GdkColor *new_color = NULL;
2199 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2200 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2202 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2203 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2205 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2206 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2207 if (new_color != NULL)
2208 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2210 gtk_widget_destroy (dialog);
2216 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2219 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2220 ModestMsgEditWindowPrivate *priv;
2221 GtkWidget *dialog = NULL;
2223 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2224 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2226 dialog = hildon_color_chooser_new ();
2227 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2228 g_free (buffer_format);
2230 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2232 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2233 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2236 gtk_widget_destroy (dialog);
2241 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2244 ModestMsgEditWindowPrivate *priv;
2245 GtkWidget *dialog = NULL;
2246 GdkColor *old_color = NULL;
2248 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2249 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2251 dialog = hildon_color_chooser_new ();
2252 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2254 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2256 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2257 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2259 gtk_widget_destroy (dialog);
2262 #endif /*!MODEST_HILDON_VERSION_0*/
2267 create_stream_for_uri (const gchar* uri)
2272 TnyStream *result = NULL;
2274 GnomeVFSHandle *handle = NULL;
2275 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2276 if (test == GNOME_VFS_OK) {
2277 TnyStream *vfssstream = TNY_STREAM (tny_vfs_stream_new (handle));
2278 /* Streams over OBEX (Bluetooth) are not seekable but
2279 * we expect them to be (we might need to read them
2280 * several times). So if this is a Bluetooth URI just
2281 * read the whole file into memory (this is not a fast
2282 * protocol so we can assume that these files are not
2283 * going to be very big) */
2284 if ((g_ascii_strncasecmp (uri, "obex://", 7) == 0)||
2285 (g_ascii_strncasecmp (uri, "upnpav://", 9) == 0)) {
2286 TnyStream *memstream = tny_camel_mem_stream_new ();
2287 tny_stream_write_to_stream (vfssstream, memstream);
2288 g_object_unref (vfssstream);
2291 result = vfssstream;
2299 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2302 ModestMsgEditWindowPrivate *priv;
2303 GtkWidget *dialog = NULL;
2305 GSList *uris = NULL;
2306 GSList *uri_node = NULL;
2308 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2310 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2311 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2312 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2314 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2316 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2317 GTK_WINDOW (dialog), GTK_WINDOW (window));
2319 response = gtk_dialog_run (GTK_DIALOG (dialog));
2321 case GTK_RESPONSE_OK:
2323 gchar *current_folder;
2324 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2325 current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
2326 if (current_folder && current_folder != '\0') {
2328 modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_INSERT_IMAGE_PATH,
2329 current_folder, &err);
2331 g_debug ("Error storing latest used folder: %s", err->message);
2335 g_free (current_folder);
2341 gtk_widget_destroy (dialog);
2343 g_object_ref (window);
2344 /* The operation could take some time so allow the dialog to be closed */
2345 while (gtk_events_pending ())
2346 gtk_main_iteration ();
2348 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2350 GnomeVFSHandle *handle = NULL;
2351 GnomeVFSResult result;
2352 GtkTextIter position;
2353 GtkTextMark *insert_mark;
2355 uri = (const gchar *) uri_node->data;
2356 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2357 if (result == GNOME_VFS_OK) {
2359 GnomeVFSFileInfo *info;
2360 gchar *filename, *basename, *escaped_filename;
2361 TnyMimePart *mime_part;
2363 const gchar *mime_type = NULL;
2364 GnomeVFSURI *vfs_uri;
2365 guint64 stream_size;
2367 gnome_vfs_close (handle);
2368 vfs_uri = gnome_vfs_uri_new (uri);
2370 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2371 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2372 g_free (escaped_filename);
2373 gnome_vfs_uri_unref (vfs_uri);
2374 info = gnome_vfs_file_info_new ();
2376 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2377 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2379 mime_type = gnome_vfs_file_info_get_mime_type (info);
2381 mime_part = tny_platform_factory_new_mime_part
2382 (modest_runtime_get_platform_factory ());
2384 TnyStream *stream = create_stream_for_uri (uri);
2386 if (stream == NULL) {
2388 modest_platform_information_banner (NULL, NULL,
2389 _FM("sfil_ib_opening_not_allowed"));
2391 g_object_unref (mime_part);
2392 gnome_vfs_file_info_unref (info);
2396 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2398 content_id = g_strdup_printf ("%d", priv->next_cid);
2399 tny_mime_part_set_content_id (mime_part, content_id);
2400 g_free (content_id);
2403 basename = g_path_get_basename (filename);
2404 tny_mime_part_set_filename (mime_part, basename);
2407 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size, window);
2409 if (pixbuf != NULL) {
2410 priv->images_size += stream_size;
2411 priv->images_count ++;
2412 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2413 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2414 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position,
2415 tny_mime_part_get_content_id (mime_part), pixbuf);
2416 g_object_unref (pixbuf);
2418 tny_list_prepend (priv->images, (GObject *) mime_part);
2419 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2421 modest_platform_information_banner (NULL, NULL,
2422 _("mail_ib_file_operation_failed"));
2426 g_object_unref (mime_part);
2427 gnome_vfs_file_info_unref (info);
2431 g_object_unref (window);
2435 on_attach_file_response (GtkDialog *dialog,
2439 GSList *uris = NULL;
2441 GnomeVFSFileSize total_size, allowed_size;
2442 ModestMsgEditWindow *window;
2443 ModestMsgEditWindowPrivate *priv;
2448 case GTK_RESPONSE_OK:
2450 gchar *current_folder;
2452 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2453 current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
2454 if (current_folder && current_folder != '\0') {
2456 modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_ATTACH_FILE_PATH,
2457 current_folder, &err);
2459 g_debug ("Error storing latest used folder: %s", err->message);
2463 g_free (current_folder);
2470 window = MODEST_MSG_EDIT_WINDOW (user_data);
2471 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2473 /* allowed size is the maximum size - what's already there */
2474 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2475 &att_num, &att_size);
2476 allowed_size = MODEST_MAX_ATTACHMENT_SIZE - att_size;
2479 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2481 const gchar *uri = (const gchar *) uri_node->data;
2484 modest_msg_edit_window_attach_file_one (window, uri, allowed_size);
2486 if (total_size > allowed_size) {
2487 g_warning ("%s: total size: %u",
2488 __FUNCTION__, (unsigned int)total_size);
2491 allowed_size -= total_size;
2493 g_slist_foreach (uris, (GFunc) g_free, NULL);
2494 g_slist_free (uris);
2496 gtk_widget_destroy (GTK_WIDGET (dialog));
2500 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2502 GtkWidget *dialog = NULL;
2503 ModestMsgEditWindowPrivate *priv;
2506 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(window));
2508 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2510 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2513 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window),
2514 GTK_FILE_CHOOSER_ACTION_OPEN);
2515 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2516 conf_folder = modest_conf_get_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_ATTACH_FILE_PATH, NULL);
2517 if (conf_folder && conf_folder[0] != '\0') {
2518 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), conf_folder);
2521 /* Set the default folder to images folder */
2522 docs_folder = g_build_filename (g_getenv (MODEST_MAEMO_UTILS_MYDOCS_ENV),
2523 ".documents", NULL);
2524 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), docs_folder);
2525 g_free (docs_folder);
2527 g_free (conf_folder);
2528 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2529 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2530 GTK_WINDOW (dialog), GTK_WINDOW (window));
2532 /* Connect to response & show */
2533 g_signal_connect (dialog, "response",
2534 G_CALLBACK (on_attach_file_response), window);
2535 gtk_widget_show (dialog);
2540 modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window,
2542 GnomeVFSFileSize allowed_size)
2545 GnomeVFSHandle *handle = NULL;
2546 ModestMsgEditWindowPrivate *priv;
2547 GnomeVFSResult result;
2548 GnomeVFSFileSize size = 0;
2549 g_return_val_if_fail (window, 0);
2550 g_return_val_if_fail (uri, 0);
2552 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2554 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2555 if (result == GNOME_VFS_OK) {
2556 TnyMimePart *mime_part;
2558 const gchar *mime_type = NULL;
2560 gchar *escaped_filename;
2563 GnomeVFSFileInfo *info;
2564 GnomeVFSURI *vfs_uri;
2566 gnome_vfs_close (handle);
2567 vfs_uri = gnome_vfs_uri_new (uri);
2570 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2571 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2572 g_free (escaped_filename);
2573 gnome_vfs_uri_unref (vfs_uri);
2575 info = gnome_vfs_file_info_new ();
2577 if (gnome_vfs_get_file_info (uri,
2579 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2581 mime_type = gnome_vfs_file_info_get_mime_type (info);
2582 mime_part = tny_platform_factory_new_mime_part
2583 (modest_runtime_get_platform_factory ());
2585 /* try to get the attachment's size; this may fail for weird
2586 * file systems, like obex, upnp... */
2587 if (allowed_size != 0 &&
2588 info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
2590 if (size > allowed_size) {
2591 modest_platform_information_banner (NULL, NULL,
2592 _FM("sfil_ib_opening_not_allowed"));
2597 g_warning ("%s: could not get attachment size", __FUNCTION__);
2599 stream = create_stream_for_uri (uri);
2601 if (stream == NULL) {
2603 modest_platform_information_banner (NULL, NULL, _FM("sfil_ib_opening_not_allowed"));
2605 g_object_unref (mime_part);
2607 gnome_vfs_file_info_unref (info);
2611 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2612 g_object_unref (stream);
2614 content_id = g_strdup_printf ("%d", priv->next_cid);
2615 tny_mime_part_set_content_id (mime_part, content_id);
2616 g_free (content_id);
2619 basename = g_path_get_basename (filename);
2620 tny_mime_part_set_filename (mime_part, basename);
2623 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2624 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2626 info->size == 0, info->size);
2627 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2628 gtk_widget_show_all (priv->attachments_caption);
2629 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2631 g_object_unref (mime_part);
2632 gnome_vfs_file_info_unref (info);
2639 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2642 ModestMsgEditWindowPrivate *priv;
2645 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2646 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2648 if (att_list == NULL) {
2649 att_list = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2650 if (!modest_maemo_utils_select_attachments (GTK_WINDOW (window), att_list, TRUE)) {
2651 g_object_unref (att_list);
2656 g_object_ref (att_list);
2659 if (tny_list_get_length (att_list) == 0) {
2660 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2662 gboolean dialog_response;
2663 gchar *message = NULL;
2664 gchar *filename = NULL;
2666 if (tny_list_get_length (att_list) == 1) {
2668 iter = tny_list_create_iterator (att_list);
2669 part = (TnyMimePart *) tny_iterator_get_current (iter);
2670 g_object_unref (iter);
2671 if (TNY_IS_MSG (part)) {
2672 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2674 filename = tny_header_dup_subject (header);
2675 g_object_unref (header);
2677 if (filename == NULL) {
2678 filename = g_strdup (_("mail_va_no_subject"));
2681 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2683 g_object_unref (part);
2685 filename = g_strdup ("");
2687 message = g_strdup_printf (ngettext("emev_nc_delete_attachment",
2688 "emev_nc_delete_attachments",
2689 tny_list_get_length (att_list)), filename);
2692 dialog_response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
2696 if (dialog_response != GTK_RESPONSE_OK) {
2697 g_object_unref (att_list);
2701 for (iter = tny_list_create_iterator (att_list);
2702 !tny_iterator_is_done (iter);
2703 tny_iterator_next (iter)) {
2704 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2705 const gchar *att_id;
2706 tny_list_remove (priv->attachments, (GObject *) mime_part);
2708 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2710 if (tny_list_get_length (priv->attachments) == 0)
2711 gtk_widget_hide (priv->attachments_caption);
2712 att_id = tny_mime_part_get_content_id (mime_part);
2714 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2716 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2717 g_object_unref (mime_part);
2719 g_object_unref (iter);
2722 g_object_unref (att_list);
2724 /* if the last attachment has been removed, focus the Subject: field */
2725 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2726 gtk_widget_grab_focus (priv->subject_field);
2730 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2733 ModestMsgEditWindowPrivate *priv;
2734 GdkColor *new_color;
2735 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2737 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2738 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2741 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2743 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2745 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2747 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2752 font_size_clicked (GtkToolButton *button,
2753 ModestMsgEditWindow *window)
2755 ModestMsgEditWindowPrivate *priv;
2756 GtkWidget *selector, *dialog;
2758 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2760 selector = hildon_touch_selector_new ();
2761 hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector), priv->sizes_model, TRUE);
2762 hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, priv->current_size_index);
2764 dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
2765 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog), HILDON_TOUCH_SELECTOR (selector));
2766 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_font_size"));
2768 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2772 WPTextBufferFormat format;
2774 new_index = hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (selector), 0);
2776 memset (&format, 0, sizeof (format));
2777 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2779 format.cs.font_size = TRUE;
2780 format.cs.text_position = TRUE;
2781 format.cs.font = TRUE;
2782 format.font_size = new_index;
2783 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2785 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2786 GINT_TO_POINTER (new_index)))
2787 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2789 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2790 size_text = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector));
2791 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
2792 size_text, "</span>", NULL);
2794 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2798 gtk_widget_destroy (dialog);
2800 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2805 font_face_clicked (GtkToolButton *button,
2806 ModestMsgEditWindow *window)
2808 ModestMsgEditWindowPrivate *priv;
2809 GtkWidget *selector, *dialog;
2810 GtkCellRenderer *renderer;
2812 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2814 selector = hildon_touch_selector_new ();
2815 renderer = gtk_cell_renderer_text_new ();
2816 hildon_touch_selector_append_column (HILDON_TOUCH_SELECTOR (selector), priv->faces_model,
2817 renderer, "family", 0, "text", 0, NULL);
2818 hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, priv->current_face_index);
2820 dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
2821 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog), HILDON_TOUCH_SELECTOR (selector));
2822 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_font_face"));
2824 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2825 gint new_font_index;
2829 new_font_index = hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (selector), 0);
2830 path = gtk_tree_path_new_from_indices (new_font_index, -1);
2831 if (gtk_tree_model_get_iter (priv->faces_model, &iter, path)) {
2835 gtk_tree_model_get (priv->faces_model, &iter, 0, &face_name, -1);
2837 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2838 GINT_TO_POINTER(new_font_index)))
2839 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2841 markup = g_strconcat ("<span font_family='", face_name, "'>Tt</span>", NULL);
2842 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2844 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2848 gtk_tree_path_free (path);
2851 gtk_widget_destroy (dialog);
2853 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2858 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2861 ModestMsgEditWindowPrivate *priv = NULL;
2862 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2864 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2865 if (!priv->update_caption_visibility)
2868 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2870 gtk_widget_show (priv->cc_caption);
2872 gtk_widget_hide (priv->cc_caption);
2874 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2878 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2881 ModestMsgEditWindowPrivate *priv = NULL;
2882 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2884 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2885 if (!priv->update_caption_visibility)
2888 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2890 gtk_widget_show (priv->bcc_caption);
2892 gtk_widget_hide (priv->bcc_caption);
2894 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2898 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2899 ModestRecptEditor *editor)
2901 ModestMsgEditWindowPrivate *priv;
2903 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2904 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2906 /* we check for low-mem; in that case, show a warning, and don't allow
2907 * for the addressbook
2909 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2912 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2914 if (editor == NULL) {
2915 GtkWidget *view_focus;
2916 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2918 /* This code should be kept in sync with ModestRecptEditor. The
2919 textview inside the recpt editor is the one that really gets the
2920 focus. As it's inside a scrolled window, and this one inside the
2921 hbox recpt editor inherits from, we'll need to go up in the
2922 hierarchy to know if the text view is part of the recpt editor
2923 or if it's a different text entry */
2925 if (gtk_widget_get_parent (view_focus)) {
2926 GtkWidget *first_parent;
2928 first_parent = gtk_widget_get_parent (view_focus);
2929 if (gtk_widget_get_parent (first_parent) &&
2930 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2931 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2936 editor = MODEST_RECPT_EDITOR (priv->to_field);
2940 modest_address_book_select_addresses (editor);
2945 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2947 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2949 modest_msg_edit_window_open_addressbook (window, NULL);
2953 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2954 gboolean show_toolbar)
2956 ModestWindowPrivate *parent_priv;
2958 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2959 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2961 /* We can not just use the code of
2962 modest_msg_edit_window_setup_toolbar because it has a
2963 mixture of both initialization and creation code. */
2965 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2967 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2971 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2972 TnyHeaderFlags priority_flags)
2974 ModestMsgEditWindowPrivate *priv;
2975 ModestWindowPrivate *parent_priv;
2977 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2979 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2980 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2982 if (priv->priority_flags != priority_flags) {
2983 GtkAction *priority_action = NULL;
2985 priv->priority_flags = priority_flags;
2987 switch (priority_flags) {
2988 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2989 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2990 MODEST_HEADER_ICON_HIGH,
2991 HILDON_ICON_SIZE_SMALL);
2992 gtk_widget_show (priv->priority_icon);
2993 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2994 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2996 case TNY_HEADER_FLAG_LOW_PRIORITY:
2997 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2998 MODEST_HEADER_ICON_LOW,
2999 HILDON_ICON_SIZE_SMALL);
3000 gtk_widget_show (priv->priority_icon);
3001 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
3002 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
3005 gtk_widget_hide (priv->priority_icon);
3006 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
3007 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
3010 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
3011 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3013 gtk_widget_queue_resize (priv->subject_box);
3017 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
3020 ModestMsgEditWindowPrivate *priv;
3021 ModestWindowPrivate *parent_priv;
3022 gint current_format;
3024 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3026 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3027 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3029 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
3030 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
3032 if (current_format != file_format) {
3033 switch (file_format) {
3034 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
3035 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
3036 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
3038 case MODEST_FILE_FORMAT_PLAIN_TEXT:
3042 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
3043 response = gtk_dialog_run (GTK_DIALOG (dialog));
3044 gtk_widget_destroy (dialog);
3045 if (response == GTK_RESPONSE_OK) {
3046 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
3048 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu"));
3049 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
3054 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3055 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3056 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
3061 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
3064 ModestMsgEditWindowPrivate *priv;
3065 WPTextBufferFormat oldfmt, fmt;
3066 gint old_position = 0;
3070 GdkColor *color = NULL;
3071 gboolean bold, bold_set, italic, italic_set;
3072 gboolean underline, underline_set;
3073 gboolean strikethrough, strikethrough_set;
3074 gboolean position_set;
3075 gboolean font_size_set, font_set, color_set;
3078 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3079 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3081 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
3082 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(),
3083 GTK_WINDOW(dialog), GTK_WINDOW (window));
3085 /* First we get the currently selected font information */
3086 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
3088 switch (oldfmt.text_position) {
3089 case TEXT_POSITION_NORMAL:
3092 case TEXT_POSITION_SUPERSCRIPT:
3100 g_object_set (G_OBJECT (dialog),
3101 "bold", oldfmt.bold != FALSE,
3102 "bold-set", !oldfmt.cs.bold,
3103 "underline", oldfmt.underline != FALSE,
3104 "underline-set", !oldfmt.cs.underline,
3105 "italic", oldfmt.italic != FALSE,
3106 "italic-set", !oldfmt.cs.italic,
3107 "strikethrough", oldfmt.strikethrough != FALSE,
3108 "strikethrough-set", !oldfmt.cs.strikethrough,
3109 "color", &oldfmt.color,
3110 "color-set", !oldfmt.cs.color,
3111 "size", wp_font_size[oldfmt.font_size],
3112 "size-set", !oldfmt.cs.font_size,
3113 "position", old_position,
3114 "position-set", !oldfmt.cs.text_position,
3115 "family", wp_get_font_name (oldfmt.font),
3116 "family-set", !oldfmt.cs.font,
3119 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
3120 GTK_WINDOW (dialog), GTK_WINDOW (window));
3121 gtk_widget_show_all (dialog);
3122 priv->font_dialog = dialog;
3123 response = gtk_dialog_run (GTK_DIALOG (dialog));
3124 priv->font_dialog = NULL;
3125 if (response == GTK_RESPONSE_OK) {
3127 g_object_get( dialog,
3129 "bold-set", &bold_set,
3130 "underline", &underline,
3131 "underline-set", &underline_set,
3133 "italic-set", &italic_set,
3134 "strikethrough", &strikethrough,
3135 "strikethrough-set", &strikethrough_set,
3137 "color-set", &color_set,
3139 "size-set", &font_size_set,
3140 "family", &font_name,
3141 "family-set", &font_set,
3142 "position", &position,
3143 "position-set", &position_set,
3148 if (response == GTK_RESPONSE_OK) {
3149 memset(&fmt, 0, sizeof(fmt));
3155 fmt.italic = italic;
3156 fmt.cs.italic = TRUE;
3158 if (underline_set) {
3159 fmt.underline = underline;
3160 fmt.cs.underline = TRUE;
3162 if (strikethrough_set) {
3163 fmt.strikethrough = strikethrough;
3164 fmt.cs.strikethrough = TRUE;
3169 ? TEXT_POSITION_NORMAL
3170 : ( ( position == 1 )
3171 ? TEXT_POSITION_SUPERSCRIPT
3172 : TEXT_POSITION_SUBSCRIPT );
3173 fmt.cs.text_position = TRUE;
3174 fmt.font_size = oldfmt.font_size;
3178 fmt.cs.color = TRUE;
3181 fmt.font = wp_get_font_index(font_name,
3186 if (font_size_set) {
3187 fmt.cs.font_size = TRUE;
3188 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
3190 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
3191 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
3193 gtk_widget_destroy (dialog);
3195 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
3199 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
3201 ModestMsgEditWindowPrivate *priv;
3203 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3204 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3206 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
3208 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3209 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3213 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
3215 ModestMsgEditWindowPrivate *priv;
3217 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3218 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3220 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
3222 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3223 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3228 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
3230 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3232 priv->can_undo = can_undo;
3236 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
3238 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3240 priv->can_redo = can_redo;
3244 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
3246 ModestMsgEditWindowPrivate *priv;
3247 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3248 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3250 return priv->can_undo;
3254 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
3256 ModestMsgEditWindowPrivate *priv;
3257 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3258 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3260 return priv->can_redo;
3265 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
3268 GtkTextIter match_start, match_end;
3270 if (image_id == NULL)
3273 gtk_text_buffer_get_start_iter (buffer, &iter);
3275 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
3276 GSList *tags = gtk_text_iter_get_tags (&match_start);
3278 for (node = tags; node != NULL; node = g_slist_next (node)) {
3279 GtkTextTag *tag = (GtkTextTag *) node->data;
3280 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
3281 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
3282 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
3284 offset = gtk_text_iter_get_offset (&match_start);
3285 gtk_text_buffer_delete (buffer, &match_start, &match_end);
3286 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
3290 gtk_text_iter_forward_char (&iter);
3295 message_is_empty (ModestMsgEditWindow *window)
3297 ModestMsgEditWindowPrivate *priv = NULL;
3299 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3300 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3302 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
3303 * so we can ignore markup.
3305 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
3308 count = gtk_text_buffer_get_char_count (buf);
3314 msg_body_focus (GtkWidget *focus,
3315 GdkEventFocus *event,
3319 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3320 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3321 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3326 recpt_field_changed (GtkTextBuffer *buffer,
3327 ModestMsgEditWindow *editor)
3329 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3330 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3334 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3336 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3337 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3341 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3344 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3345 GtkTextBuffer *buffer;
3347 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3348 gtk_text_buffer_set_modified (buffer, modified);
3349 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3350 gtk_text_buffer_set_modified (buffer, modified);
3351 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3352 gtk_text_buffer_set_modified (buffer, modified);
3353 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3357 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3359 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3360 const char *account_name;
3361 GtkTextBuffer *buffer;
3363 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3364 if (gtk_text_buffer_get_modified (buffer))
3366 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3367 if (gtk_text_buffer_get_modified (buffer))
3369 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3370 if (gtk_text_buffer_get_modified (buffer))
3372 if (gtk_text_buffer_get_modified (priv->text_buffer))
3375 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3376 if (priv->original_mailbox) {
3377 if (!account_name || strcmp (account_name, priv->original_mailbox))
3379 } else if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3390 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3392 ModestMsgEditWindowPrivate *priv = NULL;
3394 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3395 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3397 /* check if there's no recipient added */
3398 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3399 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3400 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3401 /* no recipient contents, then select contacts */
3402 modest_msg_edit_window_open_addressbook (window, NULL);
3406 g_object_ref (window);
3407 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3408 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3409 g_object_unref (window);
3412 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3413 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3414 g_object_unref (window);
3417 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3418 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3419 g_object_unref (window);
3423 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3424 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3425 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3426 g_object_unref (window);
3433 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3434 ModestMsgEditWindow *window)
3436 modest_msg_edit_window_offer_attach_file (window);
3440 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3442 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3444 return priv->clipboard_text;
3448 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3450 ModestMsgEditWindow *window)
3452 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3453 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3456 /* It could happen that the window was already closed */
3457 if (!GTK_WIDGET_VISIBLE (window))
3460 g_object_ref (window);
3461 text = gtk_clipboard_wait_for_text (selection_clipboard);
3463 if (priv->clipboard_text != NULL) {
3464 g_free (priv->clipboard_text);
3466 priv->clipboard_text = text;
3468 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3470 g_object_unref (window);
3473 static gboolean clipboard_owner_change_idle (gpointer userdata)
3475 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
3476 ModestMsgEditWindowPrivate *priv;
3478 gdk_threads_enter ();
3479 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3480 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3482 priv->clipboard_owner_idle = 0;
3483 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, window);
3484 gdk_threads_leave ();
3490 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window)
3492 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3493 if (priv->clipboard_owner_idle == 0) {
3494 priv->clipboard_owner_idle = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
3495 clipboard_owner_change_idle,
3496 g_object_ref (window),
3502 subject_field_move_cursor (GtkEntry *entry,
3503 GtkMovementStep step,
3508 /* It could happen that the window was already closed */
3509 if (!GTK_WIDGET_VISIBLE (window))
3512 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3516 update_window_title (ModestMsgEditWindow *window)
3518 ModestMsgEditWindowPrivate *priv = NULL;
3519 const gchar *subject;
3521 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3522 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3523 if (subject == NULL || subject[0] == '\0')
3524 subject = _("mail_va_new_email");
3526 gtk_window_set_title (GTK_WINDOW (window), subject);
3531 subject_field_changed (GtkEditable *editable,
3532 ModestMsgEditWindow *window)
3534 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3535 update_window_title (window);
3536 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3537 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3538 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3542 subject_field_insert_text (GtkEditable *editable,
3544 gint new_text_length,
3546 ModestMsgEditWindow *window)
3548 GString *result = g_string_new ("");
3550 gint result_len = 0;
3551 const gchar *entry_text = NULL;
3554 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3555 old_length = g_utf8_strlen (entry_text, -1);
3557 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3558 gunichar c = g_utf8_get_char_validated (current, 8);
3559 /* Invalid unichar, stop */
3565 result = g_string_append_unichar (result, c);
3569 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3570 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3573 /* Prevent endless recursion */
3574 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3575 g_signal_emit_by_name (editable, "insert-text",
3576 (gpointer) result->str, (gpointer) result->len,
3577 (gpointer) position, (gpointer) window);
3578 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3582 if (result_len + old_length > 1000) {
3583 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3584 _CS("ckdg_ib_maximum_characters_reached"));
3586 g_string_free (result, TRUE);
3590 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3593 ModestMsgEditWindowPrivate *priv = NULL;
3595 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3596 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3598 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3601 gtk_widget_show_all (priv->find_toolbar);
3602 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3604 gtk_widget_hide_all (priv->find_toolbar);
3605 gtk_widget_grab_focus (priv->msg_body);
3610 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3612 GtkTextIter *match_start,
3613 GtkTextIter *match_end)
3615 GtkTextIter end_iter;
3616 gchar *str_casefold;
3619 gchar *range_casefold;
3622 gboolean result = FALSE;
3629 gtk_text_iter_forward_to_end (&end_iter);
3631 str_casefold = g_utf8_casefold (str, -1);
3632 str_chars_n = strlen (str);
3634 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3635 range_casefold = g_utf8_casefold (range_text, -1);
3636 range_chars_n = strlen (range_casefold);
3638 if (range_chars_n < str_chars_n) {
3639 g_free (str_casefold);
3640 g_free (range_text);
3641 g_free (range_casefold);
3645 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3646 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3647 if (!g_utf8_collate (range_subtext, str_casefold)) {
3648 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3650 if (!gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3651 match_start, match_end, NULL)) {
3652 g_warning ("Matched string with collate, but not matched in model");
3654 g_free (found_text);
3656 g_free (range_subtext);
3660 g_free (str_casefold);
3661 g_free (range_text);
3662 g_free (range_casefold);
3669 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3670 ModestMsgEditWindow *window)
3672 gchar *current_search = NULL;
3673 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3675 GtkTextIter selection_start, selection_end;
3676 GtkTextIter match_start, match_end;
3677 gboolean continue_search = FALSE;
3679 if (message_is_empty (window)) {
3680 g_free (priv->last_search);
3681 priv->last_search = NULL;
3682 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3686 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3687 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3688 g_free (current_search);
3689 g_free (priv->last_search);
3690 priv->last_search = NULL;
3691 /* Information banner about empty search */
3692 hildon_banner_show_information (NULL, NULL, _CS("ecdg_ib_find_rep_enter_text"));
3696 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3697 continue_search = TRUE;
3699 g_free (priv->last_search);
3700 priv->last_search = g_strdup (current_search);
3703 if (continue_search) {
3704 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3705 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3706 &match_start, &match_end);
3708 hildon_banner_show_information (NULL, NULL, _HL("ckct_ib_find_search_complete"));
3710 GtkTextIter buffer_start;
3711 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3712 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3713 &match_start, &match_end);
3715 hildon_banner_show_information (NULL, NULL, _HL("ckct_ib_find_no_matches"));
3718 /* Mark as selected the string found in search */
3720 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3721 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3722 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3724 g_free (priv->last_search);
3725 priv->last_search = NULL;
3727 g_free (current_search);
3731 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3733 ModestMsgEditWindowPrivate *priv;
3735 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3740 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3743 ModestMsgEditWindowPrivate *priv;
3745 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3750 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3751 ModestMsgEditWindow *window)
3753 modest_msg_edit_window_toggle_find_toolbar (window, FALSE);
3757 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3760 ModestMsgEditWindowPrivate *priv;
3761 TnyHeader *header = NULL;
3763 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3764 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3766 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3768 if (priv->draft_msg != NULL) {
3769 g_object_unref (priv->draft_msg);
3772 if (draft != NULL) {
3773 g_object_ref (draft);
3774 header = tny_msg_get_header (draft);
3775 if (priv->msg_uid) {
3776 g_free (priv->msg_uid);
3777 priv->msg_uid = NULL;
3779 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3782 priv->draft_msg = draft;
3786 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3787 GtkTextIter *start, GtkTextIter *end,
3790 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3791 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3794 if (tag == NULL) return;
3795 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3796 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3797 replace_with_images (window, priv->images);
3802 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3805 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3807 g_return_if_fail (TNY_IS_MIME_PART (part));
3808 tny_list_prepend (priv->attachments, (GObject *) part);
3809 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3810 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3811 gtk_widget_show_all (priv->attachments_caption);
3812 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3816 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3818 ModestMsgEditWindowPrivate *priv;
3820 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3821 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3823 return priv->msg_uid;
3827 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3828 ModestMsgEditWindowWidgetType widget_type)
3830 ModestMsgEditWindowPrivate *priv;
3832 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3833 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3835 switch (widget_type) {
3836 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3837 return priv->msg_body;
3839 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3840 return priv->to_field;
3842 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3843 return priv->cc_field;
3845 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3846 return priv->bcc_field;
3848 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3849 return priv->subject_field;
3851 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3852 return priv->attachments_view;
3860 remove_tags (WPTextBuffer *buffer)
3862 GtkTextIter start, end;
3864 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3865 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3867 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3871 on_account_removed (TnyAccountStore *account_store,
3872 TnyAccount *account,
3875 /* Do nothing if it's a store account, because we use the
3876 transport to send the messages */
3877 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3878 const gchar *parent_acc = NULL;
3879 const gchar *our_acc = NULL;
3881 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3882 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3883 /* Close this window if I'm showing a message of the removed account */
3884 if (strcmp (parent_acc, our_acc) == 0)
3885 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3890 get_signature (const gchar *current_recipient, gboolean *has_signature)
3892 gchar *result = NULL;
3893 gchar *mailbox = NULL;
3894 gchar *account_name;
3895 ModestProtocol *protocol = NULL;
3897 *has_signature = FALSE;
3899 account_name = modest_utils_get_account_name_from_recipient (current_recipient, &mailbox);
3900 if (account_is_multimailbox (account_name, &protocol)
3902 if (MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
3903 result = modest_account_protocol_get_signature (MODEST_ACCOUNT_PROTOCOL (protocol),
3904 account_name, mailbox,
3909 if (result == NULL) {
3910 result = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (),
3911 account_name, has_signature);
3916 static void update_signature (ModestMsgEditWindow *self,
3917 const gchar *old_account,
3918 const gchar *new_account)
3920 ModestMsgEditWindowPrivate *priv;
3921 gboolean has_old_signature, has_new_signature;
3923 GtkTextIter match_start, match_end;
3924 ModestAccountMgr *mgr;
3926 gchar *full_signature;
3928 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
3930 gtk_text_buffer_begin_user_action (priv->text_buffer);
3932 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
3933 mgr = modest_runtime_get_account_mgr ();
3937 signature = get_signature (old_account, &has_old_signature);
3938 if (has_old_signature) {
3939 full_signature = g_strconcat ("\n--\n", signature, NULL);
3940 if (gtk_text_iter_forward_search (&iter, full_signature, 0, &match_start, &match_end, NULL)) {
3941 gtk_text_buffer_delete (priv->text_buffer, &match_start, &match_end);
3943 } else if (gtk_text_iter_forward_search (&iter, _("mcen_ia_editor_original_message"), 0,
3944 &match_start, &match_end, NULL)) {
3947 g_free (full_signature);
3952 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3953 signature = get_signature (new_account, &has_new_signature);
3954 if (has_new_signature) {
3955 full_signature = g_strconcat ("\n--\n", signature, NULL);
3956 gtk_text_buffer_insert (priv->text_buffer, &iter, full_signature, -1);
3957 g_free (full_signature);
3960 gtk_text_buffer_end_user_action (priv->text_buffer);
3964 from_field_changed (HildonPickerButton *button,
3965 ModestMsgEditWindow *self)
3967 ModestMsgEditWindowPrivate *priv;
3968 gchar *old_account, *new_account;
3970 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
3972 old_account = priv->last_from_account;
3973 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3974 new_account = priv->last_from_account;
3976 update_signature (self, old_account, new_account);
3980 typedef struct _MessageSettingsHelper {
3981 ModestMsgEditWindow *window;
3982 GSList *priority_group;
3983 GSList *format_group;
3984 GtkToggleButton *current_priority;
3985 GtkToggleButton *current_format;
3986 } MessageSettingsHelper;
3989 on_priority_toggle (GtkToggleButton *button,
3990 MessageSettingsHelper *helper)
3993 ModestMsgEditWindowPrivate *priv;
3995 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (helper->window);
3996 if (gtk_toggle_button_get_active (button)) {
3998 for (node = helper->priority_group; node != NULL; node = g_slist_next (node)) {
3999 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
4000 if ((node_button != button) &&
4001 gtk_toggle_button_get_active (node_button)) {
4002 gtk_toggle_button_set_active (node_button, FALSE);
4005 helper->current_priority = button;
4007 gboolean found = FALSE;
4008 /* If no one is active, activate it again */
4009 for (node = helper->priority_group; node != NULL; node = g_slist_next (node)) {
4010 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
4011 if (gtk_toggle_button_get_active (node_button)) {
4017 gtk_toggle_button_set_active (button, TRUE);
4023 on_format_toggle (GtkToggleButton *button,
4024 MessageSettingsHelper *helper)
4027 ModestMsgEditWindowPrivate *priv;
4029 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (helper->window);
4030 if (gtk_toggle_button_get_active (button)) {
4032 for (node = helper->format_group; node != NULL; node = g_slist_next (node)) {
4033 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
4034 if ((node_button != button) &&
4035 gtk_toggle_button_get_active (node_button)) {
4036 gtk_toggle_button_set_active (node_button, FALSE);
4039 helper->current_format = button;
4041 gboolean found = FALSE;
4042 /* If no one is active, activate it again */
4043 for (node = helper->format_group; node != NULL; node = g_slist_next (node)) {
4044 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
4045 if (gtk_toggle_button_get_active (node_button)) {
4051 gtk_toggle_button_set_active (button, TRUE);
4058 modest_msg_edit_window_show_msg_settings_dialog (ModestMsgEditWindow *window)
4063 GtkWidget *priority_hbox;
4064 GtkWidget *high_toggle, *medium_toggle, *low_toggle;
4065 GtkWidget *captioned;
4066 GtkSizeGroup *title_sizegroup, *value_sizegroup;
4067 GtkWidget *format_hbox;
4068 GtkWidget *html_toggle, *text_toggle;
4069 ModestMsgEditWindowPrivate *priv;
4070 MessageSettingsHelper helper = {0,};
4072 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4073 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
4074 helper.window = window;
4075 helper.priority_group = NULL;
4076 helper.format_group = NULL;
4078 title_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4079 value_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4081 dialog = gtk_dialog_new_with_buttons (_("mcen_me_message_settings"), NULL,
4082 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
4083 _HL("wdgt_bd_done"), GTK_RESPONSE_ACCEPT, NULL);
4084 vbox = gtk_vbox_new (FALSE, 0);
4085 align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
4086 gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE, 0);
4087 gtk_container_add (GTK_CONTAINER (align), vbox);
4088 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), align);
4089 gtk_widget_show (align);
4090 gtk_widget_show (vbox);
4092 /* Priority toggles */
4093 priority_hbox = gtk_hbox_new (TRUE, 0);
4094 high_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4095 gtk_button_set_label (GTK_BUTTON (high_toggle), _("mcen_me_editor_priority_high"));
4096 helper.priority_group = g_slist_prepend (helper.priority_group, high_toggle);
4097 g_object_set_data (G_OBJECT (high_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_HIGH_PRIORITY));
4098 medium_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4099 gtk_button_set_label (GTK_BUTTON (medium_toggle), _("mcen_me_editor_priority_normal"));
4100 helper.priority_group = g_slist_prepend (helper.priority_group, medium_toggle);
4101 g_object_set_data (G_OBJECT (medium_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_NORMAL_PRIORITY));
4102 low_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4103 gtk_button_set_label (GTK_BUTTON (low_toggle), _("mcen_me_editor_priority_low"));
4104 helper.priority_group = g_slist_prepend (helper.priority_group, low_toggle);
4105 g_object_set_data (G_OBJECT (low_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_LOW_PRIORITY));
4106 gtk_box_pack_start (GTK_BOX (priority_hbox), low_toggle, TRUE, TRUE, 0);
4107 gtk_box_pack_start (GTK_BOX (priority_hbox), medium_toggle, TRUE, TRUE, 0);
4108 gtk_box_pack_start (GTK_BOX (priority_hbox), high_toggle, TRUE, TRUE, 0);
4109 gtk_widget_show_all (priority_hbox);
4110 captioned = modest_maemo_utils_create_captioned (title_sizegroup, value_sizegroup,
4111 _("mcen_me_editor_message_priority"), FALSE, priority_hbox);
4112 gtk_widget_show (captioned);
4113 gtk_box_pack_start (GTK_BOX (vbox), captioned, FALSE, FALSE, 0);
4115 /* format toggles */
4116 format_hbox = gtk_hbox_new (TRUE, 0);
4117 html_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4118 gtk_button_set_label (GTK_BUTTON (html_toggle), _("mcen_me_editor_formatted_text"));
4119 helper.format_group = g_slist_prepend (helper.format_group, html_toggle);
4120 g_object_set_data (G_OBJECT (html_toggle), "format", GINT_TO_POINTER (MODEST_MSG_EDIT_FORMAT_HTML));
4121 g_object_set_data (G_OBJECT (html_toggle), "file-format", GINT_TO_POINTER (MODEST_FILE_FORMAT_FORMATTED_TEXT));
4122 text_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4123 gtk_button_set_label (GTK_BUTTON (text_toggle), _("mcen_me_editor_plain_text"));
4124 helper.format_group = g_slist_prepend (helper.format_group, text_toggle);
4125 g_object_set_data (G_OBJECT (text_toggle), "format", GINT_TO_POINTER (MODEST_MSG_EDIT_FORMAT_TEXT));
4126 g_object_set_data (G_OBJECT (text_toggle), "file-format", GINT_TO_POINTER (MODEST_FILE_FORMAT_PLAIN_TEXT));
4127 gtk_box_pack_start (GTK_BOX (format_hbox), html_toggle, TRUE, TRUE, 0);
4128 gtk_box_pack_start (GTK_BOX (format_hbox), text_toggle, TRUE, TRUE, 0);
4129 gtk_widget_show_all (format_hbox);
4130 gtk_widget_show (format_hbox);
4131 gtk_box_pack_start (GTK_BOX (vbox), format_hbox, FALSE, FALSE, 0);
4134 g_object_unref (title_sizegroup);
4135 g_object_unref (value_sizegroup);
4137 /* Set current values */
4138 switch (priv->priority_flags) {
4139 case TNY_HEADER_FLAG_HIGH_PRIORITY:
4140 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (high_toggle), TRUE);
4141 helper.current_priority = GTK_TOGGLE_BUTTON (high_toggle);
4143 case TNY_HEADER_FLAG_LOW_PRIORITY:
4144 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (low_toggle), TRUE);
4145 helper.current_priority = GTK_TOGGLE_BUTTON (low_toggle);
4148 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (medium_toggle), TRUE);
4149 helper.current_priority = GTK_TOGGLE_BUTTON (medium_toggle);
4153 switch (modest_msg_edit_window_get_format (window)) {
4154 case MODEST_MSG_EDIT_FORMAT_TEXT:
4155 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (text_toggle), TRUE);
4156 helper.current_format = GTK_TOGGLE_BUTTON (text_toggle);
4158 case MODEST_MSG_EDIT_FORMAT_HTML:
4160 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (html_toggle), TRUE);
4161 helper.current_format = GTK_TOGGLE_BUTTON (html_toggle);
4165 /* Signal connects */
4166 g_signal_connect (G_OBJECT (high_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4167 g_signal_connect (G_OBJECT (medium_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4168 g_signal_connect (G_OBJECT (low_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4169 g_signal_connect (G_OBJECT (html_toggle), "toggled", G_CALLBACK (on_format_toggle), &helper);
4170 g_signal_connect (G_OBJECT (text_toggle), "toggled", G_CALLBACK (on_format_toggle), &helper);
4172 /* Save settings if the user clicked on done */
4173 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
4174 TnyHeaderFlags flags;
4175 ModestMsgEditFormat old_format, new_format;
4177 /* Set priority flags */
4178 flags = (TnyHeaderFlags) g_object_get_data (G_OBJECT (helper.current_priority), "priority");
4179 if (priv->priority_flags != flags)
4180 modest_msg_edit_window_set_priority_flags (window, flags);
4182 /* Set edit format */
4183 old_format = modest_msg_edit_window_get_format (window);
4184 new_format = (ModestMsgEditFormat) g_object_get_data (G_OBJECT (helper.current_format), "format");
4185 if (old_format != new_format) {
4186 gint file_format = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (helper.current_format), "file-format"));
4187 modest_msg_edit_window_set_file_format (window, file_format);
4191 gtk_widget_destroy (dialog);
4192 g_slist_free (helper.priority_group);
4196 on_message_settings (GtkAction *action,
4197 ModestMsgEditWindow *window)
4199 modest_msg_edit_window_show_msg_settings_dialog (window);
4203 on_cc_button_toggled (HildonCheckButton *button,
4204 ModestMsgEditWindow *window)
4206 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
4208 modest_msg_edit_window_show_cc (MODEST_MSG_EDIT_WINDOW (window),
4209 hildon_check_button_get_active (button));
4213 on_bcc_button_toggled (HildonCheckButton *button,
4214 ModestMsgEditWindow *window)
4216 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
4218 modest_msg_edit_window_show_bcc (MODEST_MSG_EDIT_WINDOW (window),
4219 hildon_check_button_get_active (button));
4223 setup_menu (ModestMsgEditWindow *self)
4225 ModestMsgEditWindowPrivate *priv = NULL;
4227 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(self));
4229 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
4231 /* Settings menu buttons */
4232 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_editor_checknames"), NULL,
4233 APP_MENU_CALLBACK (modest_ui_actions_on_check_names),
4235 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_undo"), "<Ctrl>z",
4236 APP_MENU_CALLBACK (modest_ui_actions_on_undo),
4237 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_undo));
4239 priv->cc_button = hildon_check_button_new (0);
4240 gtk_button_set_label (GTK_BUTTON (priv->cc_button), _("mcen_me_editor_showcc"));
4241 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->cc_button),
4243 modest_hildon2_window_add_button_to_menu (MODEST_HILDON2_WINDOW (self), GTK_BUTTON (priv->cc_button),
4245 g_signal_connect (G_OBJECT (priv->cc_button), "toggled",
4246 G_CALLBACK (on_cc_button_toggled), (gpointer) self);
4247 priv->bcc_button = hildon_check_button_new (0);
4248 gtk_button_set_label (GTK_BUTTON (priv->bcc_button), _("mcen_me_editor_showbcc"));
4249 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->bcc_button),
4251 modest_hildon2_window_add_button_to_menu (MODEST_HILDON2_WINDOW (self), GTK_BUTTON (priv->bcc_button),
4253 g_signal_connect (G_OBJECT (priv->bcc_button), "toggled",
4254 G_CALLBACK (on_bcc_button_toggled), (gpointer) self);
4256 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_editor_attach_inlineimage"), NULL,
4257 APP_MENU_CALLBACK (modest_ui_actions_on_insert_image),
4258 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_set_style));
4259 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_remove_attachments"), NULL,
4260 APP_MENU_CALLBACK (modest_ui_actions_on_remove_attachments),
4261 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_editor_remove_attachment));
4262 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_message_settings"), NULL,
4263 APP_MENU_CALLBACK (on_message_settings),
4265 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_viewer_find"), "<Ctrl>f",
4266 APP_MENU_CALLBACK (modest_ui_actions_on_toggle_find_in_page),