1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37 #include <tny-vfs-stream.h>
38 #include <tny-camel-mem-stream.h>
39 #include <modest-account-protocol.h>
43 #include <modest-account-mgr.h>
44 #include <modest-account-mgr-helpers.h>
46 #include <widgets/modest-msg-edit-window.h>
47 #include <modest-selector-picker.h>
48 #include <widgets/modest-recpt-editor.h>
49 #include <widgets/modest-attachments-view.h>
51 #include <modest-runtime.h>
53 #include "modest-platform.h"
54 #include "modest-icon-names.h"
55 #include "modest-widget-memory.h"
56 #include "modest-window-priv.h"
57 #include "modest-mail-operation.h"
58 #include "modest-tny-platform-factory.h"
59 #include "modest-tny-msg.h"
60 #include "modest-tny-folder.h"
61 #include "modest-tny-account.h"
62 #include "modest-address-book.h"
63 #include "modest-text-utils.h"
64 #include <tny-simple-list.h>
65 #include <modest-wp-text-view.h>
66 #include <wptextbuffer.h>
67 #include <hildon/hildon-pannable-area.h>
68 #include <hildon/hildon-touch-selector.h>
69 #include <hildon/hildon-picker-dialog.h>
70 #include "modest-msg-edit-window-ui-dimming.h"
72 #include "modest-hildon-includes.h"
73 #ifdef MODEST_HAVE_HILDON0_WIDGETS
74 #include <hildon-widgets/hildon-color-chooser.h>
76 #include "widgets/modest-msg-edit-window-ui.h"
77 #ifdef MODEST_HAVE_HILDON0_WIDGETS
78 #include <libgnomevfs/gnome-vfs-mime-utils.h>
80 #include <libgnomevfs/gnome-vfs-mime.h>
82 #include <modest-utils.h>
83 #include "modest-maemo-utils.h"
84 #include <modest-ui-constants.h>
87 #define DEFAULT_FONT_SIZE 3
88 #define DEFAULT_FONT 2
89 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
90 #define DEFAULT_MAIN_VBOX_SPACING 6
91 #define SUBJECT_MAX_LENGTH 1000
92 #define IMAGE_MAX_WIDTH 560
93 #define DEFAULT_FONT_SCALE 1.5
94 #define ATTACHMENT_BUTTON_WIDTH 118
95 #define MAX_FROM_VALUE 48
96 #define MAX_BODY_LENGTH 4096
98 static gboolean is_wp_text_buffer_started = FALSE;
100 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
101 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
102 static void modest_msg_edit_window_finalize (GObject *obj);
104 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
105 static void body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
106 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
108 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
109 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
110 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
111 static void text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
112 GtkTextIter *start, GtkTextIter *end,
114 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
115 static void body_insert_text (GtkTextBuffer *buffer,
116 GtkTextIter *location,
119 ModestMsgEditWindow *window);
120 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
121 static void subject_field_insert_text (GtkEditable *editable,
123 gint new_text_length,
125 ModestMsgEditWindow *window);
126 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
128 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
130 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
131 ModestRecptEditor *editor);
132 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
133 ModestMsgEditWindow *window);
135 /* ModestWindow methods implementation */
136 static void modest_msg_edit_window_disconnect_signals (ModestWindow *window);
137 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
138 gboolean show_toolbar);
139 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
141 ModestMsgEditWindow *window);
142 static void modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window);
143 static void subject_field_move_cursor (GtkEntry *entry,
144 GtkMovementStep step,
148 static void update_window_title (ModestMsgEditWindow *window);
151 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
152 ModestMsgEditWindow *window);
153 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
154 ModestMsgEditWindow *window);
155 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
157 GtkTextIter *match_start,
158 GtkTextIter *match_end);
160 static void remove_tags (WPTextBuffer *buffer);
162 static void on_account_removed (TnyAccountStore *account_store,
166 static void init_window (ModestMsgEditWindow *obj);
168 gboolean scroll_drag_timeout (gpointer userdata);
169 static void correct_scroll (ModestMsgEditWindow *w);
170 static void correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused);
171 static void text_buffer_end_user_action (GtkTextBuffer *buffer,
172 ModestMsgEditWindow *userdata);
173 static void text_buffer_mark_set (GtkTextBuffer *buffer,
176 ModestMsgEditWindow *userdata);
177 static void on_message_settings (GtkAction *action,
178 ModestMsgEditWindow *window);
179 static void setup_menu (ModestMsgEditWindow *self);
181 static void from_field_changed (HildonPickerButton *button,
182 ModestMsgEditWindow *self);
183 static void font_size_clicked (GtkToolButton *button,
184 ModestMsgEditWindow *window);
185 static void font_face_clicked (GtkToolButton *button,
186 ModestMsgEditWindow *window);
187 static void update_signature (ModestMsgEditWindow *self,
188 const gchar *old_account,
189 const gchar *new_account);
190 static GtkWidget *_create_addressbook_box (GtkSizeGroup *title_size_group, GtkSizeGroup *value_size_group,
191 const gchar *label, GtkWidget *control);
192 static void DEBUG_BUFFER (WPTextBuffer *buffer)
196 g_message ("BEGIN BUFFER OF SIZE %d", gtk_text_buffer_get_char_count (GTK_TEXT_BUFFER (buffer)));
198 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &iter);
199 while (!gtk_text_iter_is_end (&iter)) {
200 GString *output = g_string_new ("");
201 GSList *toggled_tags;
204 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, FALSE);
205 g_string_append_printf (output, "%d: CLOSED [ ", gtk_text_iter_get_offset (&iter));
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, "] OPENED [ ");
214 toggled_tags = gtk_text_iter_get_toggled_tags (&iter, TRUE);
215 for (node = toggled_tags; node != NULL; node = g_slist_next (node)) {
216 GtkTextTag *tag = (GtkTextTag *) node->data;
218 g_object_get (G_OBJECT (tag), "name", &name, NULL);
219 output = g_string_append (output, name);
220 g_string_append (output, " ");
222 output = g_string_append (output, "]\n");
223 g_message ("%s", output->str);
224 g_string_free (output, TRUE);
225 gtk_text_iter_forward_to_tag_toggle (&iter, NULL);
227 g_message ("END BUFFER");
231 static const GtkActionEntry hildon2_msg_edit_action_entries [] = {
232 { "MessageSettings", NULL, N_("mcen_me_message_settings"), NULL, NULL, G_CALLBACK (on_message_settings)},
236 /* static gboolean */
237 /* on_key_pressed (GtkWidget *self, */
238 /* GdkEventKey *event, */
239 /* gpointer user_data); */
241 /* list my signals */
248 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
249 struct _ModestMsgEditWindowPrivate {
251 GtkWidget *header_box;
253 ModestPairList *from_field_protos;
254 GtkWidget *from_field;
255 gchar *last_from_account;
256 gchar *original_account_name;
261 gchar *original_mailbox;
265 GtkWidget *bcc_field;
266 GtkWidget *subject_field;
267 GtkWidget *attachments_view;
268 GtkWidget *priority_icon;
269 GtkWidget *subject_box;
270 GtkWidget *add_attachment_button;
272 GtkWidget *cc_caption;
273 GtkWidget *bcc_caption;
274 gboolean update_caption_visibility;
275 GtkWidget *attachments_caption;
277 GtkTextBuffer *text_buffer;
279 GtkWidget *font_size_toolitem;
280 GtkWidget *font_face_toolitem;
281 GtkWidget *font_color_button;
282 GtkWidget *font_color_toolitem;
283 GSList *font_items_group;
284 GtkTreeModel *faces_model;
285 gint current_face_index;
286 GtkWidget *font_tool_button_label;
287 GtkTreeModel *sizes_model;
288 gint current_size_index;
289 GtkWidget *size_tool_button_label;
291 GtkWidget *find_toolbar;
294 GtkWidget *font_dialog;
297 guint correct_scroll_idle;
298 guint scroll_drag_timeout_id;
302 TnyList *attachments;
307 TnyHeaderFlags priority_flags;
309 gboolean can_undo, can_redo;
310 gulong clipboard_change_handler_id;
311 gulong default_clipboard_change_handler_id;
312 gulong account_removed_handler_id;
313 guint clipboard_owner_idle;
314 gchar *clipboard_text;
323 GtkWidget *cc_button;
324 GtkWidget *bcc_button;
327 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
328 MODEST_TYPE_MSG_EDIT_WINDOW, \
329 ModestMsgEditWindowPrivate))
331 static GtkWindowClass *parent_class = NULL;
333 /* uncomment the following if you have defined any signals */
334 /* static guint signals[LAST_SIGNAL] = {0}; */
337 modest_msg_edit_window_get_type (void)
339 static GType my_type = 0;
341 static const GTypeInfo my_info = {
342 sizeof(ModestMsgEditWindowClass),
343 NULL, /* base init */
344 NULL, /* base finalize */
345 (GClassInitFunc) modest_msg_edit_window_class_init,
346 NULL, /* class finalize */
347 NULL, /* class data */
348 sizeof(ModestMsgEditWindow),
350 (GInstanceInitFunc) modest_msg_edit_window_init,
353 my_type = g_type_register_static (MODEST_TYPE_HILDON2_WINDOW,
354 "ModestMsgEditWindow",
362 save_state (ModestWindow *self)
364 modest_widget_memory_save (modest_runtime_get_conf(),
365 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
370 restore_settings (ModestMsgEditWindow *self)
372 ModestConf *conf = NULL;
374 conf = modest_runtime_get_conf ();
376 /* Dim at start clipboard actions */
377 modest_widget_memory_restore (conf, G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
382 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
384 GObjectClass *gobject_class;
385 ModestWindowClass *modest_window_class;
386 gobject_class = (GObjectClass*) klass;
387 modest_window_class = (ModestWindowClass*) klass;
389 parent_class = g_type_class_peek_parent (klass);
390 gobject_class->finalize = modest_msg_edit_window_finalize;
392 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
393 modest_window_class->save_state_func = save_state;
394 modest_window_class->disconnect_signals_func = modest_msg_edit_window_disconnect_signals;
396 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
400 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
402 ModestMsgEditWindowPrivate *priv;
403 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
405 priv->msg_body = NULL;
406 priv->from_field = NULL;
407 priv->to_field = NULL;
408 priv->cc_field = NULL;
409 priv->bcc_field = NULL;
410 priv->subject_field = NULL;
411 priv->attachments = TNY_LIST (tny_simple_list_new ());
412 priv->images = TNY_LIST (tny_simple_list_new ());
413 priv->images_size = 0;
414 priv->images_count = 0;
417 priv->cc_caption = NULL;
418 priv->bcc_caption = NULL;
419 priv->update_caption_visibility = FALSE;
421 priv->priority_flags = 0;
423 priv->find_toolbar = NULL;
424 priv->last_search = NULL;
426 priv->draft_msg = NULL;
427 priv->outbox_msg = NULL;
428 priv->msg_uid = NULL;
430 priv->can_undo = FALSE;
431 priv->can_redo = FALSE;
432 priv->clipboard_change_handler_id = 0;
433 priv->default_clipboard_change_handler_id = 0;
434 priv->account_removed_handler_id = 0;
435 priv->clipboard_owner_idle = 0;
436 priv->clipboard_text = NULL;
439 priv->scroll_drag_timeout_id = 0;
440 priv->correct_scroll_idle = 0;
441 priv->last_upper = 0.0;
443 priv->font_dialog = NULL;
444 priv->app_menu = NULL;
446 priv->references = NULL;
447 priv->in_reply_to = NULL;
449 if (!is_wp_text_buffer_started) {
450 is_wp_text_buffer_started = TRUE;
451 wp_text_buffer_library_init ();
456 hildon_program_add_window (hildon_program_get_instance(),
461 multimailbox_get_default_mailbox (const gchar *account_name)
463 gchar *transport_account;
464 gchar *result = NULL;
466 transport_account = modest_account_mgr_get_server_account_name (modest_runtime_get_account_mgr (),
468 TNY_ACCOUNT_TYPE_TRANSPORT);
469 if (transport_account) {
471 ModestProtocolRegistry *registry;
473 registry = modest_runtime_get_protocol_registry ();
475 proto = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), transport_account,
476 MODEST_ACCOUNT_PROTO, TRUE);
478 ModestProtocol *protocol =
479 modest_protocol_registry_get_protocol_by_name (registry,
480 MODEST_PROTOCOL_REGISTRY_TRANSPORT_PROTOCOLS,
482 if (MODEST_ACCOUNT_PROTOCOL (protocol)) {
483 ModestPairList *pair_list;
485 pair_list = modest_account_protocol_get_from_list (MODEST_ACCOUNT_PROTOCOL (protocol),
488 ModestPair *pair = (ModestPair *) pair_list->data;
489 result = g_strdup ((const gchar *) pair->first);
490 modest_pair_list_free (pair_list);
501 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
503 static ModestPairList*
504 get_transports (void)
506 GSList *transports = NULL;
508 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
509 GSList *accounts = modest_account_mgr_account_names (account_mgr,
510 TRUE /* only enabled accounts. */);
512 GSList *cursor = accounts;
514 gchar *account_name = cursor->data;
517 gchar *transport_account;
518 gboolean multi_mailbox = FALSE;
519 ModestProtocol *protocol = NULL;
521 if (modest_account_mgr_account_is_multimailbox (account_mgr, account_name, &protocol)) {
523 transport_account = modest_account_mgr_get_server_account_name
524 (modest_runtime_get_account_mgr (),
526 TNY_ACCOUNT_TYPE_TRANSPORT);
527 if (protocol && MODEST_IS_ACCOUNT_PROTOCOL (protocol)) {
528 ModestPairList *pair_list;
529 pair_list = modest_account_protocol_get_from_list (MODEST_ACCOUNT_PROTOCOL (protocol),
532 transports = g_slist_concat (transports, pair_list);
533 multi_mailbox = TRUE;
538 if (!multi_mailbox) {
539 gchar *from_string = NULL;
541 from_string = modest_account_mgr_get_from_string (account_mgr,
543 if (from_string && account_name) {
544 gchar *name = account_name;
545 ModestPair *pair = modest_pair_new ((gpointer) name,
546 (gpointer) from_string , TRUE);
547 transports = g_slist_prepend (transports, pair);
552 cursor = cursor->next;
554 g_slist_free (accounts); /* only free the accounts, not the elements,
555 * because they are used in the pairlist */
559 static void window_focus (GtkWindow *window,
563 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
567 scroll_drag_timeout (gpointer userdata)
569 ModestMsgEditWindow *win = (ModestMsgEditWindow *) userdata;
570 ModestMsgEditWindowPrivate *priv;
572 /* It could happen that the window was already closed */
573 if (!GTK_WIDGET_VISIBLE (win))
576 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(win);
578 correct_scroll_without_drag_check (win, TRUE);
580 priv->scroll_drag_timeout_id = 0;
586 correct_scroll_without_drag_check_idle (gpointer userdata)
588 ModestMsgEditWindow *w = (ModestMsgEditWindow *) userdata;
589 ModestMsgEditWindowPrivate *priv;
591 GdkRectangle rectangle;
592 gint offset_min, offset_max;
596 /* It could happen that the window was already closed */
597 if (!GTK_WIDGET_VISIBLE (w))
600 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
602 insert = gtk_text_buffer_get_insert (priv->text_buffer);
603 gtk_text_buffer_get_iter_at_mark (priv->text_buffer, &iter, insert);
605 gtk_text_view_get_iter_location (GTK_TEXT_VIEW (priv->msg_body), &iter, &rectangle);
606 offset_min = priv->msg_body->allocation.y + rectangle.y;
607 offset_max = offset_min + rectangle.height;
609 vadj = hildon_pannable_area_get_vadjustment (HILDON_PANNABLE_AREA (priv->pannable));
610 offset_min = MAX (offset_min - 48, 0);
611 offset_max = MIN (offset_max + 48, vadj->upper);
613 gtk_adjustment_clamp_page (vadj, (gdouble) offset_min, (gdouble) offset_max);
615 priv->correct_scroll_idle = 0;
620 correct_scroll_without_drag_check (ModestMsgEditWindow *w, gboolean only_if_focused)
622 ModestMsgEditWindowPrivate *priv;
624 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
626 if (only_if_focused && !gtk_widget_is_focus (priv->msg_body))
629 if (priv->correct_scroll_idle > 0) {
633 priv->correct_scroll_idle = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
634 (GSourceFunc) correct_scroll_without_drag_check_idle,
640 correct_scroll (ModestMsgEditWindow *w)
642 ModestMsgEditWindowPrivate *priv;
644 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(w);
645 if (gtk_grab_get_current () == priv->msg_body) {
646 if (priv->scroll_drag_timeout_id == 0) {
647 priv->scroll_drag_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT,
649 (GSourceFunc) scroll_drag_timeout,
656 correct_scroll_without_drag_check (w, TRUE);
660 text_buffer_end_user_action (GtkTextBuffer *buffer,
661 ModestMsgEditWindow *userdata)
664 correct_scroll (userdata);
668 text_buffer_mark_set (GtkTextBuffer *buffer,
671 ModestMsgEditWindow *userdata)
673 gtk_text_buffer_begin_user_action (buffer);
674 gtk_text_buffer_end_user_action (buffer);
678 cut_clipboard_check (GtkTextView *text_view,
681 GtkTextBuffer *buffer;
683 buffer = gtk_text_view_get_buffer (text_view);
684 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
685 g_signal_stop_emission_by_name ((gpointer )text_view, "cut-clipboard");
690 copy_clipboard_check (GtkTextView *text_view,
693 GtkTextBuffer *buffer;
695 buffer = gtk_text_view_get_buffer (text_view);
696 if (!modest_text_utils_buffer_selection_is_valid (buffer)) {
697 g_signal_stop_emission_by_name ((gpointer )text_view, "copy-clipboard");
702 attachment_deleted (ModestAttachmentsView *attachments_view,
705 modest_msg_edit_window_remove_attachments (MODEST_MSG_EDIT_WINDOW (user_data),
710 connect_signals (ModestMsgEditWindow *obj)
712 ModestMsgEditWindowPrivate *priv;
714 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
716 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
717 G_CALLBACK (text_buffer_refresh_attributes), obj);
718 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
719 G_CALLBACK (text_buffer_can_undo), obj);
720 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
721 G_CALLBACK (text_buffer_can_redo), obj);
722 g_signal_connect (G_OBJECT (priv->text_buffer), "changed",
723 G_CALLBACK (body_changed), obj);
724 g_signal_connect (G_OBJECT (priv->text_buffer), "insert-text",
725 G_CALLBACK (body_insert_text), obj);
726 g_signal_connect (G_OBJECT (priv->text_buffer), "modified-changed",
727 G_CALLBACK (body_changed), obj);
728 g_signal_connect (G_OBJECT (priv->text_buffer), "end-user-action",
729 G_CALLBACK (text_buffer_end_user_action), obj);
730 g_signal_connect (G_OBJECT (priv->text_buffer), "mark-set",
731 G_CALLBACK (text_buffer_mark_set), obj);
732 g_signal_connect_after (G_OBJECT (priv->text_buffer), "apply-tag",
733 G_CALLBACK (text_buffer_apply_tag), obj);
734 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
735 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
736 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
737 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
738 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
739 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
741 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
742 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
743 g_signal_connect (G_OBJECT (priv->from_field), "value-changed",
744 G_CALLBACK (from_field_changed), obj);
746 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
747 G_CALLBACK (msg_body_focus), obj);
748 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
749 G_CALLBACK (msg_body_focus), obj);
750 g_signal_connect (G_OBJECT (obj), "set-focus", G_CALLBACK (window_focus), obj);
751 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
752 "changed", G_CALLBACK (recpt_field_changed), obj);
753 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
754 "changed", G_CALLBACK (recpt_field_changed), obj);
755 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
756 "changed", G_CALLBACK (recpt_field_changed), obj);
757 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
758 g_signal_connect_after (G_OBJECT (priv->subject_field), "move-cursor", G_CALLBACK (subject_field_move_cursor), obj);
759 g_signal_connect (G_OBJECT (priv->subject_field), "insert-text", G_CALLBACK (subject_field_insert_text), obj);
761 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
762 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
764 priv->clipboard_change_handler_id =
765 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
766 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
767 priv->default_clipboard_change_handler_id =
768 g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
769 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
771 g_signal_connect (G_OBJECT (priv->msg_body), "cut-clipboard", G_CALLBACK (cut_clipboard_check), NULL);
772 g_signal_connect (G_OBJECT (priv->msg_body), "copy-clipboard", G_CALLBACK (copy_clipboard_check), NULL);
773 g_signal_connect (G_OBJECT (priv->attachments_view), "delete", G_CALLBACK (attachment_deleted), obj);
777 init_wp_text_view_style ()
779 static gboolean initialized = FALSE;
782 gtk_rc_parse_string ("class \"WPTextView\" style \"fremantle-textview\"");
788 init_window (ModestMsgEditWindow *obj)
790 GtkWidget *to_caption, *subject_caption;
791 GtkWidget *main_vbox;
792 GtkWidget *add_attachment_align;
793 ModestMsgEditWindowPrivate *priv;
794 GtkActionGroup *action_group;
795 ModestWindowPrivate *parent_priv;
796 GdkPixbuf *window_icon = NULL;
797 GError *error = NULL;
799 GtkSizeGroup *title_size_group;
800 GtkSizeGroup *value_size_group;
801 GtkWidget *attachment_icon;
802 GtkWidget *window_box;
803 GtkWidget *window_align;
804 #if (GTK_MINOR_VERSION >= 10)
805 GdkAtom deserialize_type;
808 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
809 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
811 parent_priv->ui_manager = gtk_ui_manager_new();
812 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
813 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
815 /* Add common actions */
816 gtk_action_group_add_actions (action_group,
817 modest_msg_edit_action_entries,
818 G_N_ELEMENTS (modest_msg_edit_action_entries),
820 gtk_action_group_add_actions (action_group,
821 hildon2_msg_edit_action_entries,
822 G_N_ELEMENTS (hildon2_msg_edit_action_entries),
824 gtk_action_group_add_toggle_actions (action_group,
825 modest_msg_edit_toggle_action_entries,
826 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
828 gtk_action_group_add_radio_actions (action_group,
829 modest_msg_edit_alignment_radio_action_entries,
830 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
832 G_CALLBACK (modest_ui_actions_on_change_justify),
834 gtk_action_group_add_radio_actions (action_group,
835 modest_msg_edit_priority_action_entries,
836 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
838 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
840 gtk_action_group_add_radio_actions (action_group,
841 modest_msg_edit_file_format_action_entries,
842 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
843 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
844 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
846 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
847 g_object_unref (action_group);
849 /* Load the UI definition */
850 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
853 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
854 g_clear_error (&error);
857 /* Add accelerators */
858 gtk_window_add_accel_group (GTK_WINDOW (obj),
859 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
861 parent_priv->menubar = NULL;
863 title_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
864 value_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
866 /* Note: This ModestPairList* must exist for as long as the picker
867 * that uses it, because the ModestSelectorPicker uses the ID opaquely,
868 * so it can't know how to manage its memory. */
869 priv->from_field = modest_selector_picker_new (MODEST_EDITABLE_SIZE,
870 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
872 modest_selector_picker_set_value_max_chars (MODEST_SELECTOR_PICKER (priv->from_field), MAX_FROM_VALUE);
873 modest_maemo_utils_set_hbutton_layout (title_size_group, value_size_group,
874 _("mail_va_from"), priv->from_field);
875 hildon_button_set_title_alignment (HILDON_BUTTON (priv->from_field), 0.5, 0.5);
877 priv->to_field = modest_recpt_editor_new ();
878 priv->cc_field = modest_recpt_editor_new ();
879 priv->bcc_field = modest_recpt_editor_new ();
880 modest_recpt_editor_set_show_abook_button (MODEST_RECPT_EDITOR (priv->to_field), FALSE);
881 modest_recpt_editor_set_show_abook_button (MODEST_RECPT_EDITOR (priv->cc_field), FALSE);
882 modest_recpt_editor_set_show_abook_button (MODEST_RECPT_EDITOR (priv->bcc_field), FALSE);
883 priv->subject_box = gtk_hbox_new (FALSE, MODEST_MARGIN_NONE);
884 priv->priority_icon = gtk_image_new ();
885 gtk_box_pack_start (GTK_BOX (priv->subject_box), priv->priority_icon, FALSE, FALSE, 0);
886 priv->subject_field = hildon_entry_new (MODEST_EDITABLE_SIZE);
887 gtk_entry_set_max_length (GTK_ENTRY (priv->subject_field) ,SUBJECT_MAX_LENGTH);
888 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
889 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
890 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
891 gtk_box_pack_start (GTK_BOX (priv->subject_box), priv->subject_field, TRUE, TRUE, 0);
892 priv->add_attachment_button = hildon_button_new (MODEST_EDITABLE_SIZE, HILDON_BUTTON_ARRANGEMENT_VERTICAL);
893 gtk_widget_set_size_request (priv->add_attachment_button, ATTACHMENT_BUTTON_WIDTH, -1);
894 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
895 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
896 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, HILDON_ICON_SIZE_FINGER);
897 hildon_button_set_image (HILDON_BUTTON (priv->add_attachment_button), attachment_icon);
898 add_attachment_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
899 gtk_alignment_set_padding (GTK_ALIGNMENT (add_attachment_align), 0, 0, MODEST_MARGIN_DEFAULT, 0);
900 gtk_container_add (GTK_CONTAINER (add_attachment_align), priv->add_attachment_button);
901 gtk_box_pack_start (GTK_BOX (priv->subject_box), add_attachment_align, FALSE, FALSE, 0);
902 priv->attachments_view = modest_attachments_view_new (NULL);
903 modest_attachments_view_set_style (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
904 MODEST_ATTACHMENTS_VIEW_STYLE_NO_FOCUS);
906 priv->header_box = gtk_vbox_new (FALSE, 0);
908 to_caption = _create_addressbook_box
909 (title_size_group, value_size_group,
910 _("mail_va_to"), priv->to_field);
911 priv->cc_caption = _create_addressbook_box
912 (title_size_group, value_size_group,
913 _("mail_va_cc"), priv->cc_field);
914 priv->bcc_caption = _create_addressbook_box
915 (title_size_group, value_size_group,
916 _("mail_va_hotfix1"), priv->bcc_field);
917 subject_caption = modest_maemo_utils_create_captioned (title_size_group, value_size_group,
918 _("mail_va_subject"), FALSE, priv->subject_box);
919 priv->attachments_caption = modest_maemo_utils_create_captioned_with_size_type (title_size_group, value_size_group,
920 _("mail_va_attachment"),
922 priv->attachments_view,
923 HILDON_SIZE_AUTO_WIDTH |
924 HILDON_SIZE_AUTO_HEIGHT);
925 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), value_size_group); */
926 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), value_size_group); */
927 /* modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), value_size_group); */
928 g_object_unref (title_size_group);
929 g_object_unref (value_size_group);
931 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->from_field, FALSE, FALSE, 0);
932 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
933 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
934 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
935 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
936 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
937 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
939 init_wp_text_view_style ();
941 priv->msg_body = modest_wp_text_view_new ();
944 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
945 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
946 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
947 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
948 #if (GTK_MINOR_VERSION >= 10)
949 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), NULL);
950 deserialize_type = gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer),
952 gtk_text_buffer_deserialize_set_can_create_tags (GTK_TEXT_BUFFER (priv->text_buffer),
953 deserialize_type, TRUE);
955 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
957 priv->find_toolbar = hildon_find_toolbar_new (NULL);
958 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
960 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
962 priv->pannable = hildon_pannable_area_new ();
964 g_object_set (G_OBJECT (priv->pannable), "hscrollbar-policy", GTK_POLICY_NEVER, NULL);
966 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
967 window_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
968 gtk_alignment_set_padding (GTK_ALIGNMENT (window_align), 0, 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DEFAULT);
970 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
971 gtk_box_pack_start (GTK_BOX(main_vbox), priv->msg_body, TRUE, TRUE, 0);
972 gtk_container_add (GTK_CONTAINER (window_align), main_vbox);
974 hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA (priv->pannable), window_align);
975 gtk_widget_show_all (GTK_WIDGET(priv->pannable));
977 window_box = gtk_vbox_new (FALSE, 0);
978 gtk_container_add (GTK_CONTAINER(obj), window_box);
980 gtk_box_pack_start (GTK_BOX (window_box), priv->pannable, TRUE, TRUE, 0);
982 /* Set window icon */
983 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON, MODEST_ICON_SIZE_BIG);
985 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
986 g_object_unref (window_icon);
991 modest_msg_edit_window_disconnect_signals (ModestWindow *window)
993 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
995 if (gtk_clipboard_get (GDK_SELECTION_PRIMARY) &&
996 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
997 priv->clipboard_change_handler_id))
998 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
999 priv->clipboard_change_handler_id);
1000 if (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD) &&
1001 g_signal_handler_is_connected (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
1002 priv->default_clipboard_change_handler_id))
1003 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
1004 priv->default_clipboard_change_handler_id);
1006 if (priv->account_removed_handler_id &&
1007 g_signal_handler_is_connected (modest_runtime_get_account_store (),
1008 priv->account_removed_handler_id))
1009 g_signal_handler_disconnect(modest_runtime_get_account_store (),
1010 priv->account_removed_handler_id);
1014 modest_msg_edit_window_finalize (GObject *obj)
1016 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1018 /* Sanity check: shouldn't be needed, the window mgr should
1019 call this function before */
1020 modest_msg_edit_window_disconnect_signals (MODEST_WINDOW (obj));
1022 if (priv->font_dialog != NULL) {
1023 gtk_dialog_response (GTK_DIALOG (priv->font_dialog), GTK_RESPONSE_NONE);
1026 if (priv->clipboard_text != NULL) {
1027 g_free (priv->clipboard_text);
1028 priv->clipboard_text = NULL;
1031 if (priv->draft_msg != NULL) {
1032 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
1033 if (TNY_IS_HEADER (header)) {
1034 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1035 modest_window_mgr_unregister_header (mgr, header);
1037 g_object_unref (priv->draft_msg);
1038 priv->draft_msg = NULL;
1040 if (priv->outbox_msg != NULL) {
1041 TnyHeader *header = tny_msg_get_header (priv->outbox_msg);
1042 if (TNY_IS_HEADER (header)) {
1043 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
1044 modest_window_mgr_unregister_header (mgr, header);
1046 g_object_unref (priv->outbox_msg);
1047 priv->outbox_msg = NULL;
1049 if (priv->correct_scroll_idle > 0) {
1050 g_source_remove (priv->correct_scroll_idle);
1051 priv->correct_scroll_idle = 0;
1053 if (priv->scroll_drag_timeout_id > 0) {
1054 g_source_remove (priv->scroll_drag_timeout_id);
1055 priv->scroll_drag_timeout_id = 0;
1057 if (priv->clipboard_owner_idle > 0) {
1058 g_source_remove (priv->clipboard_owner_idle);
1059 priv->clipboard_owner_idle = 0;
1061 if (priv->original_account_name)
1062 g_free (priv->original_account_name);
1063 if (priv->original_mailbox)
1064 g_free (priv->original_mailbox);
1065 g_free (priv->msg_uid);
1066 g_free (priv->last_search);
1067 g_free (priv->references);
1068 g_free (priv->in_reply_to);
1069 g_object_unref (priv->faces_model);
1070 g_object_unref (priv->sizes_model);
1071 g_object_unref (priv->attachments);
1072 g_object_unref (priv->images);
1074 /* This had to stay alive for as long as the picker that used it: */
1075 modest_pair_list_free (priv->from_field_protos);
1077 G_OBJECT_CLASS(parent_class)->finalize (obj);
1081 pixbuf_size_prepared (GdkPixbufLoader *loader,
1084 ModestMsgEditWindow *self)
1086 gint new_height, new_width;
1089 new_height = height;
1093 if (width > IMAGE_MAX_WIDTH) {
1094 new_height = height * IMAGE_MAX_WIDTH / width;
1095 new_width = IMAGE_MAX_WIDTH;
1098 gdk_pixbuf_loader_set_size (loader, new_width, new_height);
1102 pixbuf_from_stream (TnyStream *stream,
1103 const gchar *mime_type,
1104 guint64 *stream_size,
1105 ModestMsgEditWindow *self)
1107 GdkPixbufLoader *loader;
1110 GError *error = NULL;
1114 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1116 if (loader == NULL) {
1121 g_signal_connect (G_OBJECT (loader), "size-prepared", G_CALLBACK (pixbuf_size_prepared), self);
1123 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), TRUE);
1125 tny_stream_reset (TNY_STREAM (stream));
1126 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1127 unsigned char read_buffer[128];
1129 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1131 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, &error)) {
1134 /* Allow some UI responsiveness */
1135 while (gtk_events_pending ())
1136 gtk_main_iteration ();
1138 hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), FALSE);
1140 gdk_pixbuf_loader_close (loader, &error);
1143 g_error_free (error);
1144 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1146 g_object_ref (pixbuf);
1147 g_object_unref (loader);
1152 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1153 GdkPixbuf *new_pixbuf;
1155 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1156 gdk_pixbuf_get_width (pixbuf);
1157 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1158 g_object_unref (pixbuf);
1159 pixbuf = new_pixbuf;
1163 *stream_size = size;
1169 replace_with_images (ModestMsgEditWindow *self, TnyList *attachments)
1171 ModestMsgEditWindowPrivate *priv;
1174 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1176 g_object_ref (self);
1177 for (iter = tny_list_create_iterator (attachments);
1178 !tny_iterator_is_done (iter);
1179 tny_iterator_next (iter)) {
1180 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1181 const gchar *cid = tny_mime_part_get_content_id (part);
1182 const gchar *mime_type = tny_mime_part_get_content_type (part);
1183 if ((cid != NULL)&&(mime_type != NULL)) {
1184 guint64 stream_size;
1185 TnyStream *stream = tny_mime_part_get_decoded_stream (part);
1186 GdkPixbuf *pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size, self);
1189 g_object_unref (stream);
1191 if (pixbuf != NULL) {
1192 priv->images_count ++;
1193 priv->images_size += stream_size;
1194 wp_text_buffer_replace_image (WP_TEXT_BUFFER (priv->text_buffer), cid, pixbuf);
1195 g_object_unref (pixbuf);
1198 g_object_unref (part);
1200 g_object_unref (iter);
1201 g_object_unref (self);
1205 get_related_images (ModestMsgEditWindow *self, TnyMsg *msg)
1207 TnyMimePart *parent = NULL;
1208 const gchar *content_type = NULL;
1209 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1211 content_type = tny_mime_part_get_content_type (TNY_MIME_PART (msg));
1213 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1214 parent = g_object_ref (msg);
1215 } else if (content_type && !g_strcasecmp (content_type, "multipart/mixed")) {
1216 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1219 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
1220 iter = tny_list_create_iterator (parts);
1221 while (!tny_iterator_is_done (iter)) {
1223 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1224 content_type = tny_mime_part_get_content_type (part);
1225 if (content_type && !g_strcasecmp (content_type, "multipart/related")) {
1229 g_object_unref (part);
1231 tny_iterator_next (iter);
1233 g_object_unref (iter);
1234 g_object_unref (parts);
1237 if (parent != NULL) {
1238 TnyList *parts = TNY_LIST (tny_simple_list_new ());
1241 tny_mime_part_get_parts (TNY_MIME_PART (parent), parts);
1242 iter = tny_list_create_iterator (parts);
1243 while (!tny_iterator_is_done (iter)) {
1245 part = TNY_MIME_PART (tny_iterator_get_current (iter));
1246 content_type = tny_mime_part_get_content_type (part);
1247 if (content_type && g_str_has_prefix (content_type, "image/")) {
1248 tny_list_prepend (priv->images, (GObject *) part);
1250 g_object_unref (part);
1251 tny_iterator_next (iter);
1253 g_object_unref (iter);
1254 g_object_unref (parts);
1255 g_object_unref (parent);
1260 update_next_cid (ModestMsgEditWindow *self, TnyList *attachments)
1263 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1265 for (iter = tny_list_create_iterator (attachments) ;
1266 !tny_iterator_is_done (iter);
1267 tny_iterator_next (iter)) {
1268 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (iter);
1269 const gchar *cid = tny_mime_part_get_content_id (part);
1271 char *invalid = NULL;
1272 gint int_cid = strtol (cid, &invalid, 10);
1273 if ((invalid != NULL) && (*invalid == '\0') && (int_cid >= priv->next_cid)) {
1274 priv->next_cid = int_cid + 1;
1277 g_object_unref (part);
1279 g_object_unref (iter);
1283 set_msg (ModestMsgEditWindow *self, TnyMsg *msg, gboolean preserve_is_rich)
1286 gchar *to, *cc, *bcc, *subject;
1288 ModestMsgEditWindowPrivate *priv;
1289 ModestWindowPrivate *parent_priv;
1291 TnyHeaderFlags priority_flags;
1292 TnyFolder *msg_folder;
1293 gboolean is_html = FALSE;
1294 gboolean field_view_set;
1296 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1297 g_return_if_fail (TNY_IS_MSG (msg));
1299 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1300 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1302 header = tny_msg_get_header (msg);
1303 to = tny_header_dup_to (header);
1304 cc = tny_header_dup_cc (header);
1305 bcc = tny_header_dup_bcc (header);
1306 subject = tny_header_dup_subject (header);
1308 modest_tny_msg_get_references (TNY_MSG (msg), NULL, &(priv->references), &(priv->in_reply_to));
1309 priority_flags = tny_header_get_priority (header);
1312 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
1314 field_view_set = TRUE;
1316 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
1317 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
1318 gtk_widget_show (priv->cc_caption);
1319 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
1320 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1321 gtk_widget_hide (priv->cc_caption);
1322 field_view_set = FALSE;
1324 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->cc_button), field_view_set);
1326 field_view_set = TRUE;
1328 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
1329 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
1330 gtk_widget_show (priv->bcc_caption);
1331 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
1332 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1333 gtk_widget_hide (priv->bcc_caption);
1334 field_view_set = FALSE;
1336 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->bcc_button), field_view_set);
1340 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
1341 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
1344 update_window_title (self);
1346 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1347 body = modest_tny_msg_get_body (msg, TRUE, &is_html);
1349 if ((body == NULL)||(body[0] == '\0')) {
1351 body = modest_text_utils_convert_to_html ("");
1354 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1355 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
1358 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
1361 /* Add attachments to the view */
1362 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
1363 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1364 if (tny_list_get_length (priv->attachments) == 0) {
1365 gtk_widget_hide (priv->attachments_caption);
1367 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1368 gtk_widget_show_all (priv->attachments_caption);
1370 get_related_images (self, msg);
1371 update_next_cid (self, priv->attachments);
1372 update_next_cid (self, priv->images);
1373 replace_with_images (self, priv->images);
1375 if (preserve_is_rich && !is_html) {
1376 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1377 /* Get the default format required from configuration */
1378 } else if (!preserve_is_rich && !modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
1379 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1382 /* Set the default focus depending on having already a To: field or not */
1383 if ((!to)||(*to == '\0')) {
1384 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
1386 gtk_widget_grab_focus (priv->msg_body);
1389 DEBUG_BUFFER (WP_TEXT_BUFFER (priv->text_buffer));
1391 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1392 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
1394 modest_msg_edit_window_set_modified (self, FALSE);
1396 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1397 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1398 text_buffer_can_undo (priv->text_buffer, FALSE, self);
1399 text_buffer_can_redo (priv->text_buffer, FALSE, self);
1401 if (priv->msg_uid) {
1402 g_free (priv->msg_uid);
1403 priv->msg_uid = NULL;
1406 /* we should set a reference to the incoming message if it is a draft */
1407 msg_folder = tny_msg_get_folder (msg);
1409 if (modest_tny_folder_is_local_folder (msg_folder)) {
1410 TnyFolderType type = modest_tny_folder_get_local_or_mmc_folder_type (msg_folder);
1411 if (type == TNY_FOLDER_TYPE_INVALID)
1412 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1414 if (type == TNY_FOLDER_TYPE_DRAFTS)
1415 priv->draft_msg = g_object_ref(msg);
1416 if (type == TNY_FOLDER_TYPE_OUTBOX)
1417 priv->outbox_msg = g_object_ref(msg);
1418 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
1420 g_object_unref (msg_folder);
1431 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
1433 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1434 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1435 GtkWidget *placeholder;
1436 GtkWidget *tool_item;
1441 GtkWidget *sizes_menu;
1442 GtkWidget *fonts_menu;
1448 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
1449 gtk_toolbar_set_show_arrow (GTK_TOOLBAR (parent_priv->toolbar), FALSE);
1450 gtk_toolbar_set_icon_size (GTK_TOOLBAR (parent_priv->toolbar), HILDON_ICON_SIZE_FINGER);
1451 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
1453 /* Font color placeholder */
1454 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
1455 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1458 priv->font_color_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1459 priv->font_color_button = hildon_color_button_new ();
1460 gtk_widget_set_size_request (priv->font_color_button, -1, 48);
1461 GTK_WIDGET_UNSET_FLAGS (priv->font_color_toolitem, GTK_CAN_FOCUS);
1462 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
1463 gtk_container_add (GTK_CONTAINER (priv->font_color_toolitem), priv->font_color_button);
1464 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1465 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->font_color_toolitem), TRUE);
1466 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->font_color_toolitem), insert_index);
1467 g_signal_connect_swapped (G_OBJECT (priv->font_color_button),
1469 G_CALLBACK (modest_msg_edit_window_color_button_change),
1472 /* Font size and face placeholder */
1473 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
1474 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1476 tool_item = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
1477 priv->size_tool_button_label = gtk_label_new (NULL);
1478 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
1479 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
1480 size_text, "</span>", NULL);
1481 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1482 gtk_misc_set_alignment (GTK_MISC (priv->size_tool_button_label), 1.0, 0.5);
1484 hildon_helper_set_logical_font (priv->size_tool_button_label, "LargeSystemFont");
1485 hbox = gtk_hbox_new (MODEST_MARGIN_DEFAULT, FALSE);
1486 gtk_box_pack_start (GTK_BOX (hbox), priv->size_tool_button_label, TRUE, TRUE, 0);
1487 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1488 gtk_misc_set_alignment (GTK_MISC (arrow), 0.0, 0.5);
1489 gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
1490 gtk_widget_set_sensitive (arrow, FALSE);
1491 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), hbox);
1492 sizes_menu = gtk_menu_new ();
1493 priv->sizes_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
1494 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
1497 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
1498 gtk_list_store_append (GTK_LIST_STORE (priv->sizes_model), &iter);
1500 gtk_list_store_set (GTK_LIST_STORE (priv->sizes_model), &iter,
1504 if (wp_font_size[size_index] == 12)
1505 priv->current_size_index = size_index;
1509 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (font_size_clicked), window);
1510 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1511 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1512 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1513 priv->font_size_toolitem = tool_item;
1516 tool_item = GTK_WIDGET (gtk_tool_button_new (NULL, NULL));
1517 priv->font_tool_button_label = gtk_label_new (NULL);
1518 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
1519 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1520 gtk_misc_set_alignment (GTK_MISC (priv->font_tool_button_label), 1.0, 0.5);
1522 hildon_helper_set_logical_font (priv->font_tool_button_label, "LargeSystemFont");
1523 hbox = gtk_hbox_new (MODEST_MARGIN_DEFAULT, FALSE);
1524 gtk_box_pack_start (GTK_BOX (hbox), priv->font_tool_button_label, TRUE, TRUE, 0);
1525 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
1526 gtk_misc_set_alignment (GTK_MISC (arrow), 0.0, 0.5);
1527 gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
1528 gtk_widget_set_sensitive (arrow, FALSE);
1529 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), hbox);
1530 fonts_menu = gtk_menu_new ();
1531 priv->faces_model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
1532 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
1535 gtk_list_store_append (GTK_LIST_STORE (priv->faces_model), &iter);
1537 gtk_list_store_set (GTK_LIST_STORE (priv->faces_model), &iter,
1538 0, wp_get_font_name (font_index),
1541 if (font_index == DEFAULT_FONT)
1542 priv->current_face_index = font_index;
1544 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (font_face_clicked), window);
1545 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
1546 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1547 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1548 priv->font_face_toolitem = tool_item;
1550 /* Set expand and homogeneous for remaining items */
1551 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
1552 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1553 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1554 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1555 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1556 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1557 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1558 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
1559 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
1561 /* Explicitelly show all the toolbar (a normal gtk_widget_show
1562 will not show the tool items added to the placeholders) */
1563 gtk_widget_show_all (parent_priv->toolbar);
1565 /* Set the no show all *after* showing all items. We do not
1566 want the toolbar to be shown with a show all because it
1567 could go agains the gconf setting regarding showing or not
1568 the toolbar of the editor window */
1569 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1575 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name, const gchar *mailbox, gboolean preserve_is_rich)
1578 ModestWindowPrivate *parent_priv;
1579 ModestMsgEditWindowPrivate *priv;
1580 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1581 ModestDimmingRulesGroup *clipboard_rules_group = NULL;
1582 ModestWindowMgr *mgr = NULL;
1584 g_return_val_if_fail (msg, NULL);
1585 g_return_val_if_fail (account_name, NULL);
1587 mgr = modest_runtime_get_window_mgr ();
1589 obj = G_OBJECT (modest_window_mgr_get_msg_edit_window (mgr));
1591 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
1592 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
1594 /* Menubar. Update the state of some toggles */
1595 priv->from_field_protos = get_transports ();
1596 priv->original_mailbox = NULL;
1597 modest_selector_picker_set_pair_list (MODEST_SELECTOR_PICKER (priv->from_field), priv->from_field_protos);
1598 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1599 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1600 if (mailbox && modest_pair_list_find_by_first_as_string (priv->from_field_protos, mailbox)) {
1601 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) mailbox);
1602 priv->original_mailbox = g_strdup (mailbox);
1603 } else if (modest_account_mgr_account_is_multimailbox (modest_runtime_get_account_mgr (), account_name, NULL)) {
1604 /* We set the first mailbox as the active mailbox */
1605 priv->original_mailbox = multimailbox_get_default_mailbox (account_name);
1606 if (priv->original_mailbox != NULL)
1607 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field),
1608 (gpointer) priv->original_mailbox);
1610 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field),
1611 (gpointer) account_name);
1613 modest_selector_picker_set_active_id (MODEST_SELECTOR_PICKER (priv->from_field), (gpointer) account_name);
1615 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1616 hildon_button_set_title (HILDON_BUTTON (priv->from_field),
1618 hildon_button_set_value (HILDON_BUTTON (priv->from_field),
1619 hildon_touch_selector_get_current_text
1620 (HILDON_TOUCH_SELECTOR (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (priv->from_field)))));
1621 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
1622 hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar));
1625 connect_signals (MODEST_MSG_EDIT_WINDOW(obj));
1627 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
1629 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
1630 modest_window_set_active_mailbox (MODEST_WINDOW(obj), priv->original_mailbox);
1632 priv->original_account_name = (account_name) ? g_strdup (account_name) : NULL;
1634 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1635 clipboard_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_CLIPBOARD, FALSE);
1636 /* Add common dimming rules */
1637 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1638 modest_msg_edit_window_toolbar_dimming_entries,
1639 G_N_ELEMENTS (modest_msg_edit_window_toolbar_dimming_entries),
1640 MODEST_WINDOW (obj));
1641 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_color_toolitem,
1642 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1643 MODEST_WINDOW (obj));
1644 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_size_toolitem,
1645 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1646 MODEST_WINDOW (obj));
1647 modest_dimming_rules_group_add_widget_rule (toolbar_rules_group, priv->font_face_toolitem,
1648 G_CALLBACK (modest_ui_dimming_rules_on_set_style),
1649 MODEST_WINDOW (obj));
1650 /* Insert dimming rules group for this window */
1651 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1652 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, clipboard_rules_group);
1654 /* Setup app menu */
1655 setup_menu (MODEST_MSG_EDIT_WINDOW (obj));
1657 /* Checks the dimming rules */
1658 g_object_unref (toolbar_rules_group);
1659 g_object_unref (clipboard_rules_group);
1660 gtk_widget_hide (priv->priority_icon);
1661 gtk_widget_queue_resize (priv->subject_box);
1662 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg, preserve_is_rich);
1664 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
1666 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (obj));
1667 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (obj));
1668 modest_window_check_dimming_rules_group (MODEST_WINDOW (obj), MODEST_DIMMING_RULES_CLIPBOARD);
1669 priv->update_caption_visibility = TRUE;
1671 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (obj), FALSE);
1673 /* Track account-removed signal, this window should be closed
1674 in the case we're creating a mail associated to the account
1676 priv->account_removed_handler_id =
1677 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
1679 G_CALLBACK(on_account_removed),
1682 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (MODEST_MSG_EDIT_WINDOW (obj));
1684 return (ModestWindow*) obj;
1688 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1690 GString **string_buffer = (GString **) user_data;
1692 *string_buffer = g_string_append (*string_buffer, buffer);
1698 * @result: A new string which should be freed with g_free().
1701 get_formatted_data (ModestMsgEditWindow *edit_window)
1703 ModestMsgEditWindowPrivate *priv;
1704 GString *string_buffer = g_string_new ("");
1706 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1708 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1710 modest_text_utils_hyperlinkify (string_buffer);
1712 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1714 return g_string_free (string_buffer, FALSE);
1719 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1722 const gchar *account_name;
1723 ModestMsgEditWindowPrivate *priv;
1724 TnyIterator *att_iter;
1725 const gchar *picker_active_id;
1727 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1729 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1731 picker_active_id = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
1732 g_return_val_if_fail (picker_active_id, NULL);
1733 account_name = modest_utils_get_account_name_from_recipient (picker_active_id, NULL);
1735 /* don't free these (except from) */
1736 data = g_slice_new0 (MsgData);
1737 data->from = g_strdup ((gchar *) modest_selector_picker_get_active_display_name (MODEST_SELECTOR_PICKER (priv->from_field)));
1738 data->account_name = g_strdup (account_name);
1739 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1740 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1741 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1742 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1743 data->references = g_strdup (priv->references);
1744 data->in_reply_to = g_strdup (priv->in_reply_to);
1745 if (priv->draft_msg) {
1746 data->draft_msg = g_object_ref (priv->draft_msg);
1747 } else if (priv->outbox_msg) {
1748 data->draft_msg = g_object_ref (priv->outbox_msg);
1750 data->draft_msg = NULL;
1753 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1755 gtk_text_buffer_get_bounds (buf, &b, &e);
1756 data->plain_body = modest_text_utils_text_buffer_get_text (priv->text_buffer); /* returns a copy */
1758 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1759 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1761 data->html_body = NULL;
1763 /* deep-copy the data */
1764 att_iter = tny_list_create_iterator (priv->attachments);
1765 data->attachments = NULL;
1766 while (!tny_iterator_is_done (att_iter)) {
1767 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1768 if (!(TNY_IS_MIME_PART(part))) {
1769 g_warning ("strange data in attachment list");
1770 g_object_unref (part);
1771 tny_iterator_next (att_iter);
1774 data->attachments = g_list_append (data->attachments,
1776 tny_iterator_next (att_iter);
1778 g_object_unref (att_iter);
1780 GtkTextTagTable *tag_table = gtk_text_buffer_get_tag_table (GTK_TEXT_BUFFER (priv->text_buffer));
1781 att_iter = tny_list_create_iterator (priv->images);
1782 data->images = NULL;
1783 while (!tny_iterator_is_done (att_iter)) {
1784 TnyMimePart *part = (TnyMimePart *) tny_iterator_get_current (att_iter);
1786 if (!(TNY_IS_MIME_PART(part))) {
1787 g_warning ("strange data in attachment list");
1788 g_object_unref (part);
1789 tny_iterator_next (att_iter);
1792 cid = tny_mime_part_get_content_id (part);
1794 gchar *image_tag_id;
1795 GtkTextTag *image_tag;
1797 image_tag_id = g_strdup_printf ("image-tag-%s", cid);
1798 image_tag = gtk_text_tag_table_lookup (tag_table, image_tag_id);
1799 g_free (image_tag_id);
1801 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
1803 ((gtk_text_iter_has_tag (&iter, image_tag))||
1804 (gtk_text_iter_forward_to_tag_toggle (&iter, image_tag))))
1805 data->images = g_list_append (data->images,
1806 g_object_ref (part));
1808 g_object_unref (part);
1809 tny_iterator_next (att_iter);
1811 g_object_unref (att_iter);
1813 data->priority_flags = priv->priority_flags;
1820 unref_gobject (GObject *obj, gpointer data)
1822 if (!G_IS_OBJECT(obj))
1824 g_object_unref (obj);
1828 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1831 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1839 g_free (data->from);
1840 g_free (data->subject);
1841 g_free (data->plain_body);
1842 g_free (data->html_body);
1843 g_free (data->account_name);
1844 g_free (data->references);
1845 g_free (data->in_reply_to);
1847 if (data->draft_msg != NULL) {
1848 g_object_unref (data->draft_msg);
1849 data->draft_msg = NULL;
1852 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1853 g_list_free (data->attachments);
1854 g_list_foreach (data->images, (GFunc)unref_gobject, NULL);
1855 g_list_free (data->images);
1857 g_slice_free (MsgData, data);
1861 modest_msg_edit_window_get_parts_size (ModestMsgEditWindow *window,
1863 guint64 *parts_size)
1865 ModestMsgEditWindowPrivate *priv;
1867 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1869 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), parts_count, parts_size);
1871 /* TODO: add images */
1872 *parts_size += priv->images_size;
1873 *parts_count += priv->images_count;
1878 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1881 ModestMsgEditWindowPrivate *priv = NULL;
1882 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1884 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1886 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1888 return MODEST_MSG_EDIT_FORMAT_HTML;
1890 return MODEST_MSG_EDIT_FORMAT_TEXT;
1894 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1895 ModestMsgEditFormat format)
1897 ModestMsgEditWindowPrivate *priv;
1899 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1900 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1903 case MODEST_MSG_EDIT_FORMAT_HTML:
1904 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1906 case MODEST_MSG_EDIT_FORMAT_TEXT:
1907 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1910 g_return_if_reached ();
1914 ModestMsgEditFormatState *
1915 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1917 ModestMsgEditFormatState *format_state = NULL;
1918 ModestMsgEditWindowPrivate *priv;
1919 WPTextBufferFormat *buffer_format;
1921 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1923 buffer_format = g_new0 (WPTextBufferFormat, 1);
1924 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1926 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1928 format_state = g_new0 (ModestMsgEditFormatState, 1);
1929 format_state->bold = buffer_format->bold&0x1;
1930 format_state->italics = buffer_format->italic&0x1;
1931 format_state->bullet = buffer_format->bullet&0x1;
1932 format_state->color = buffer_format->color;
1933 format_state->font_size = buffer_format->font_size;
1934 format_state->font_family = wp_get_font_name (buffer_format->font);
1935 format_state->justification = buffer_format->justification;
1936 g_free (buffer_format);
1938 return format_state;
1943 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1944 const ModestMsgEditFormatState *format_state)
1946 ModestMsgEditWindowPrivate *priv;
1947 WPTextBufferFormat *buffer_format;
1948 WPTextBufferFormat *current_format;
1950 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1951 g_return_if_fail (format_state != NULL);
1953 buffer_format = g_new0 (WPTextBufferFormat, 1);
1954 current_format = g_new0 (WPTextBufferFormat, 1);
1956 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1957 gtk_widget_grab_focus (priv->msg_body);
1958 buffer_format->bold = (format_state->bold != FALSE);
1959 buffer_format->italic = (format_state->italics != FALSE);
1960 buffer_format->color = format_state->color;
1961 buffer_format->font_size = format_state->font_size;
1962 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1963 buffer_format->justification = format_state->justification;
1964 buffer_format->bullet = format_state->bullet;
1966 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1968 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1969 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1970 buffer_format->cs.color = !gdk_color_equal(&(buffer_format->color), &(current_format->color));
1971 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1972 buffer_format->cs.font = (buffer_format->font != current_format->font);
1973 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1974 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1976 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1977 if (buffer_format->cs.bold) {
1978 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD,
1979 GINT_TO_POINTER (buffer_format->bold&0x1));
1981 if (buffer_format->cs.italic) {
1982 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC,
1983 GINT_TO_POINTER (buffer_format->italic&0x1));
1985 if (buffer_format->cs.color) {
1986 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
1987 GINT_TO_POINTER (&(buffer_format->color)));
1989 if (buffer_format->cs.font_size) {
1990 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1991 GINT_TO_POINTER (buffer_format->font_size));
1993 if (buffer_format->cs.justification) {
1994 switch (buffer_format->justification) {
1995 case GTK_JUSTIFY_LEFT:
1996 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT,
1997 GINT_TO_POINTER(TRUE));
1999 case GTK_JUSTIFY_CENTER:
2000 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER,
2001 GINT_TO_POINTER(TRUE));
2003 case GTK_JUSTIFY_RIGHT:
2004 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT,
2005 GINT_TO_POINTER(TRUE));
2012 if (buffer_format->cs.font) {
2013 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2014 GINT_TO_POINTER (buffer_format->font));
2016 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
2017 if (buffer_format->cs.bullet) {
2018 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET,
2019 GINT_TO_POINTER ((buffer_format->bullet)?1:0));
2021 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
2023 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), self);
2025 g_free (buffer_format);
2026 g_free (current_format);
2028 /* Check dimming rules */
2029 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2030 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
2034 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
2036 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2038 ModestWindowPrivate *parent_priv;
2039 ModestMsgEditWindowPrivate *priv;
2041 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2042 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2044 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
2045 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu");
2046 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2047 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
2049 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatPlainTextMenu");
2050 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
2051 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
2054 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2056 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2057 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
2059 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2060 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
2062 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu"); */
2063 /* modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet); */
2066 switch (buffer_format->justification)
2068 case GTK_JUSTIFY_LEFT:
2069 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2071 case GTK_JUSTIFY_CENTER:
2072 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2074 case GTK_JUSTIFY_RIGHT:
2075 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2082 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
2084 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
2085 G_CALLBACK (modest_msg_edit_window_color_button_change),
2087 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
2088 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
2089 G_CALLBACK (modest_msg_edit_window_color_button_change),
2092 if (priv->current_size_index != buffer_format->font_size) {
2096 path = gtk_tree_path_new_from_indices (buffer_format->font_size, -1);
2097 if (gtk_tree_model_get_iter (priv->sizes_model, &iter, path)) {
2101 priv->current_size_index = buffer_format->font_size;
2103 gtk_tree_model_get (priv->sizes_model, &iter, 0, &size_text, -1);
2104 markup = g_strconcat ("<span font_family='Sans'>",
2105 size_text, "</span>", NULL);
2107 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2111 gtk_tree_path_free (path);
2114 if (priv->current_face_index != buffer_format->font) {
2118 path = gtk_tree_path_new_from_indices (buffer_format->font, -1);
2119 if (gtk_tree_model_get_iter (priv->faces_model, &iter, path)) {
2123 priv->current_face_index = buffer_format->font;
2124 gtk_tree_model_get (priv->faces_model, &iter, 0, &face_name, -1);
2125 markup = g_strconcat ("<span font_family='", face_name, "'>Tt</span>", NULL);
2126 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2133 g_free (buffer_format);
2137 #ifdef MODEST_HILDON_VERSION_0
2139 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2142 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2143 ModestMsgEditWindowPrivate *priv;
2144 GtkWidget *dialog = NULL;
2146 GdkColor *new_color = NULL;
2148 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2149 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2151 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2152 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
2153 g_free (buffer_format);
2155 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2156 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2157 if (new_color != NULL) {
2158 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2159 (gpointer) new_color);
2162 gtk_widget_destroy (dialog);
2167 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2170 ModestMsgEditWindowPrivate *priv;
2171 GtkWidget *dialog = NULL;
2173 GdkColor *old_color = NULL;
2174 const GdkColor *new_color = NULL;
2176 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2177 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2179 dialog = hildon_color_selector_new (GTK_WINDOW (window));
2180 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
2182 if (gtk_dialog_run (GTK_DIALOG (dialog) == GTK_RESPONSE_OK)) {
2183 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
2184 if (new_color != NULL)
2185 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
2187 gtk_widget_destroy (dialog);
2193 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
2196 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
2197 ModestMsgEditWindowPrivate *priv;
2198 GtkWidget *dialog = NULL;
2200 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2201 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
2203 dialog = hildon_color_chooser_new ();
2204 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
2205 g_free (buffer_format);
2207 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2209 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2210 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR,
2213 gtk_widget_destroy (dialog);
2218 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
2221 ModestMsgEditWindowPrivate *priv;
2222 GtkWidget *dialog = NULL;
2223 GdkColor *old_color = NULL;
2225 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2226 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
2228 dialog = hildon_color_chooser_new ();
2229 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
2231 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2233 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
2234 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), &col);
2236 gtk_widget_destroy (dialog);
2239 #endif /*!MODEST_HILDON_VERSION_0*/
2244 create_stream_for_uri (const gchar* uri)
2249 TnyStream *result = NULL;
2251 GnomeVFSHandle *handle = NULL;
2252 GnomeVFSResult test = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2253 if (test == GNOME_VFS_OK) {
2254 TnyStream *vfssstream = TNY_STREAM (tny_vfs_stream_new (handle));
2255 /* Streams over OBEX (Bluetooth) are not seekable but
2256 * we expect them to be (we might need to read them
2257 * several times). So if this is a Bluetooth URI just
2258 * read the whole file into memory (this is not a fast
2259 * protocol so we can assume that these files are not
2260 * going to be very big) */
2261 if ((g_ascii_strncasecmp (uri, "obex://", 7) == 0)||
2262 (g_ascii_strncasecmp (uri, "upnpav://", 9) == 0)) {
2263 TnyStream *memstream = tny_camel_mem_stream_new ();
2264 tny_stream_write_to_stream (vfssstream, memstream);
2265 g_object_unref (vfssstream);
2268 result = vfssstream;
2276 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
2279 ModestMsgEditWindowPrivate *priv;
2280 GtkWidget *dialog = NULL;
2282 GSList *uris = NULL;
2283 GSList *uri_node = NULL;
2285 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2287 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
2288 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
2289 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2291 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
2293 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2294 GTK_WINDOW (dialog), GTK_WINDOW (window));
2296 response = gtk_dialog_run (GTK_DIALOG (dialog));
2298 case GTK_RESPONSE_OK:
2300 gchar *current_folder;
2301 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2302 current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
2303 if (current_folder && current_folder != '\0') {
2305 modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_INSERT_IMAGE_PATH,
2306 current_folder, &err);
2308 g_debug ("Error storing latest used folder: %s", err->message);
2312 g_free (current_folder);
2318 gtk_widget_destroy (dialog);
2320 g_object_ref (window);
2321 /* The operation could take some time so allow the dialog to be closed */
2322 while (gtk_events_pending ())
2323 gtk_main_iteration ();
2325 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2327 GnomeVFSHandle *handle = NULL;
2328 GnomeVFSResult result;
2329 GtkTextIter position;
2330 GtkTextMark *insert_mark;
2332 uri = (const gchar *) uri_node->data;
2333 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2334 if (result == GNOME_VFS_OK) {
2336 GnomeVFSFileInfo *info;
2337 gchar *filename, *basename, *escaped_filename;
2338 TnyMimePart *mime_part;
2340 const gchar *mime_type = NULL;
2341 GnomeVFSURI *vfs_uri;
2342 guint64 stream_size;
2344 gnome_vfs_close (handle);
2345 vfs_uri = gnome_vfs_uri_new (uri);
2347 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2348 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2349 g_free (escaped_filename);
2350 gnome_vfs_uri_unref (vfs_uri);
2351 info = gnome_vfs_file_info_new ();
2353 if (gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
2354 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
2356 mime_type = gnome_vfs_file_info_get_mime_type (info);
2358 mime_part = tny_platform_factory_new_mime_part
2359 (modest_runtime_get_platform_factory ());
2361 TnyStream *stream = create_stream_for_uri (uri);
2363 if (stream == NULL) {
2365 modest_platform_information_banner (NULL, NULL,
2366 _FM("sfil_ib_opening_not_allowed"));
2368 g_object_unref (mime_part);
2369 gnome_vfs_file_info_unref (info);
2373 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2375 content_id = g_strdup_printf ("%d", priv->next_cid);
2376 tny_mime_part_set_content_id (mime_part, content_id);
2377 g_free (content_id);
2380 basename = g_path_get_basename (filename);
2381 tny_mime_part_set_filename (mime_part, basename);
2384 pixbuf = pixbuf_from_stream (stream, mime_type, &stream_size, window);
2386 if (pixbuf != NULL) {
2387 priv->images_size += stream_size;
2388 priv->images_count ++;
2389 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
2390 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
2391 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position,
2392 tny_mime_part_get_content_id (mime_part), pixbuf);
2393 g_object_unref (pixbuf);
2395 tny_list_prepend (priv->images, (GObject *) mime_part);
2396 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2398 modest_platform_information_banner (NULL, NULL,
2399 _("mail_ib_file_operation_failed"));
2403 g_object_unref (mime_part);
2404 gnome_vfs_file_info_unref (info);
2408 g_object_unref (window);
2412 on_attach_file_response (GtkDialog *dialog,
2416 GSList *uris = NULL;
2418 GnomeVFSFileSize total_size, allowed_size;
2419 ModestMsgEditWindow *window;
2420 ModestMsgEditWindowPrivate *priv;
2425 case GTK_RESPONSE_OK:
2427 gchar *current_folder;
2429 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
2430 current_folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dialog));
2431 if (current_folder && current_folder != '\0') {
2433 modest_conf_set_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_ATTACH_FILE_PATH,
2434 current_folder, &err);
2436 g_debug ("Error storing latest used folder: %s", err->message);
2440 g_free (current_folder);
2447 window = MODEST_MSG_EDIT_WINDOW (user_data);
2448 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2450 /* allowed size is the maximum size - what's already there */
2451 modest_attachments_view_get_sizes (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2452 &att_num, &att_size);
2453 allowed_size = MODEST_MAX_ATTACHMENT_SIZE - att_size;
2456 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
2458 const gchar *uri = (const gchar *) uri_node->data;
2461 modest_msg_edit_window_attach_file_one (window, uri, allowed_size);
2463 if (total_size > allowed_size) {
2464 g_warning ("%s: total size: %u",
2465 __FUNCTION__, (unsigned int)total_size);
2468 allowed_size -= total_size;
2470 g_slist_foreach (uris, (GFunc) g_free, NULL);
2471 g_slist_free (uris);
2473 gtk_widget_destroy (GTK_WIDGET (dialog));
2477 modest_msg_edit_window_offer_attach_file (ModestMsgEditWindow *window)
2479 GtkWidget *dialog = NULL;
2480 ModestMsgEditWindowPrivate *priv;
2483 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(window));
2485 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2487 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2490 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window),
2491 GTK_FILE_CHOOSER_ACTION_OPEN);
2492 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
2493 conf_folder = modest_conf_get_string (modest_runtime_get_conf (), MODEST_CONF_LATEST_ATTACH_FILE_PATH, NULL);
2494 if (conf_folder && conf_folder[0] != '\0') {
2495 gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog), conf_folder);
2498 /* Set the default folder to images folder */
2499 docs_folder = g_build_filename (g_getenv (MODEST_MAEMO_UTILS_MYDOCS_ENV),
2500 ".documents", NULL);
2501 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), docs_folder);
2502 g_free (docs_folder);
2504 g_free (conf_folder);
2505 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
2506 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
2507 GTK_WINDOW (dialog), GTK_WINDOW (window));
2509 /* Connect to response & show */
2510 g_signal_connect (dialog, "response",
2511 G_CALLBACK (on_attach_file_response), window);
2512 gtk_widget_show (dialog);
2517 modest_msg_edit_window_attach_file_one (ModestMsgEditWindow *window,
2519 GnomeVFSFileSize allowed_size)
2522 GnomeVFSHandle *handle = NULL;
2523 ModestMsgEditWindowPrivate *priv;
2524 GnomeVFSResult result;
2525 GnomeVFSFileSize size = 0;
2526 g_return_val_if_fail (window, 0);
2527 g_return_val_if_fail (uri, 0);
2529 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2531 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
2532 if (result == GNOME_VFS_OK) {
2533 TnyMimePart *mime_part;
2535 const gchar *mime_type = NULL;
2537 gchar *escaped_filename;
2540 GnomeVFSFileInfo *info;
2541 GnomeVFSURI *vfs_uri;
2543 gnome_vfs_close (handle);
2544 vfs_uri = gnome_vfs_uri_new (uri);
2547 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
2548 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
2549 g_free (escaped_filename);
2550 gnome_vfs_uri_unref (vfs_uri);
2552 info = gnome_vfs_file_info_new ();
2554 if (gnome_vfs_get_file_info (uri,
2556 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
2558 mime_type = gnome_vfs_file_info_get_mime_type (info);
2559 mime_part = tny_platform_factory_new_mime_part
2560 (modest_runtime_get_platform_factory ());
2562 /* try to get the attachment's size; this may fail for weird
2563 * file systems, like obex, upnp... */
2564 if (allowed_size != 0 &&
2565 info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
2567 if (size > allowed_size) {
2568 modest_platform_information_banner (NULL, NULL,
2569 _FM("sfil_ib_opening_not_allowed"));
2574 g_warning ("%s: could not get attachment size", __FUNCTION__);
2576 stream = create_stream_for_uri (uri);
2578 if (stream == NULL) {
2580 modest_platform_information_banner (NULL, NULL, _FM("sfil_ib_opening_not_allowed"));
2582 g_object_unref (mime_part);
2584 gnome_vfs_file_info_unref (info);
2588 tny_mime_part_construct (mime_part, stream, mime_type, "base64");
2589 g_object_unref (stream);
2591 content_id = g_strdup_printf ("%d", priv->next_cid);
2592 tny_mime_part_set_content_id (mime_part, content_id);
2593 g_free (content_id);
2596 basename = g_path_get_basename (filename);
2597 tny_mime_part_set_filename (mime_part, basename);
2600 tny_list_prepend (priv->attachments, (GObject *) mime_part);
2601 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2603 info->size == 0, info->size);
2604 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
2605 gtk_widget_show_all (priv->attachments_caption);
2606 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2608 g_object_unref (mime_part);
2609 gnome_vfs_file_info_unref (info);
2616 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
2619 ModestMsgEditWindowPrivate *priv;
2622 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2623 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2625 if (att_list == NULL) {
2626 att_list = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2627 if (!modest_maemo_utils_select_attachments (GTK_WINDOW (window), att_list, TRUE)) {
2628 g_object_unref (att_list);
2633 g_object_ref (att_list);
2636 if (tny_list_get_length (att_list) == 0) {
2637 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
2639 gboolean dialog_response;
2640 gchar *message = NULL;
2641 gchar *filename = NULL;
2643 if (tny_list_get_length (att_list) == 1) {
2645 iter = tny_list_create_iterator (att_list);
2646 part = (TnyMimePart *) tny_iterator_get_current (iter);
2647 g_object_unref (iter);
2648 if (TNY_IS_MSG (part)) {
2649 TnyHeader *header = tny_msg_get_header (TNY_MSG (part));
2651 filename = tny_header_dup_subject (header);
2652 g_object_unref (header);
2654 if (filename == NULL) {
2655 filename = g_strdup (_("mail_va_no_subject"));
2658 filename = g_strdup (tny_mime_part_get_filename (TNY_MIME_PART (part)));
2660 g_object_unref (part);
2662 filename = g_strdup ("");
2664 message = g_strdup_printf (ngettext("emev_nc_delete_attachment",
2665 "emev_nc_delete_attachments",
2666 tny_list_get_length (att_list)), filename);
2669 dialog_response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
2673 if (dialog_response != GTK_RESPONSE_OK) {
2674 g_object_unref (att_list);
2678 for (iter = tny_list_create_iterator (att_list);
2679 !tny_iterator_is_done (iter);
2680 tny_iterator_next (iter)) {
2681 TnyMimePart *mime_part = (TnyMimePart *) tny_iterator_get_current (iter);
2682 const gchar *att_id;
2683 tny_list_remove (priv->attachments, (GObject *) mime_part);
2685 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2687 if (tny_list_get_length (priv->attachments) == 0)
2688 gtk_widget_hide (priv->attachments_caption);
2689 att_id = tny_mime_part_get_content_id (mime_part);
2691 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
2693 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2694 g_object_unref (mime_part);
2696 g_object_unref (iter);
2699 g_object_unref (att_list);
2701 /* if the last attachment has been removed, focus the Subject: field */
2702 if (!modest_attachments_view_has_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view)))
2703 gtk_widget_grab_focus (priv->subject_field);
2707 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
2710 ModestMsgEditWindowPrivate *priv;
2711 GdkColor *new_color;
2712 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2714 #ifdef MODEST_HAVE_HILDON0_WIDGETS
2715 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
2718 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
2720 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
2722 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
2724 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
2729 font_size_clicked (GtkToolButton *button,
2730 ModestMsgEditWindow *window)
2732 ModestMsgEditWindowPrivate *priv;
2733 GtkWidget *selector, *dialog;
2735 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2737 selector = hildon_touch_selector_new ();
2738 hildon_touch_selector_append_text_column (HILDON_TOUCH_SELECTOR (selector), priv->sizes_model, TRUE);
2739 hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, priv->current_size_index);
2741 dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
2742 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog), HILDON_TOUCH_SELECTOR (selector));
2743 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_font_size"));
2745 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2749 WPTextBufferFormat format;
2751 new_index = hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (selector), 0);
2753 memset (&format, 0, sizeof (format));
2754 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
2756 format.cs.font_size = TRUE;
2757 format.cs.text_position = TRUE;
2758 format.cs.font = TRUE;
2759 format.font_size = new_index;
2760 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
2762 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
2763 GINT_TO_POINTER (new_index)))
2764 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2766 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2767 size_text = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector));
2768 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
2769 size_text, "</span>", NULL);
2771 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
2775 gtk_widget_destroy (dialog);
2777 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2782 font_face_clicked (GtkToolButton *button,
2783 ModestMsgEditWindow *window)
2785 ModestMsgEditWindowPrivate *priv;
2786 GtkWidget *selector, *dialog;
2787 GtkCellRenderer *renderer;
2789 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2791 selector = hildon_touch_selector_new ();
2792 renderer = gtk_cell_renderer_text_new ();
2793 g_object_set (G_OBJECT (renderer), "alignment", PANGO_ALIGN_CENTER, "xalign", 0.5, NULL);
2794 hildon_touch_selector_append_column (HILDON_TOUCH_SELECTOR (selector), priv->faces_model,
2795 renderer, "family", 0, "text", 0, NULL);
2796 hildon_touch_selector_set_active (HILDON_TOUCH_SELECTOR (selector), 0, priv->current_face_index);
2798 dialog = hildon_picker_dialog_new (GTK_WINDOW (window));
2799 hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (dialog), HILDON_TOUCH_SELECTOR (selector));
2800 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_font_face"));
2802 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
2803 gint new_font_index;
2807 new_font_index = hildon_touch_selector_get_active (HILDON_TOUCH_SELECTOR (selector), 0);
2808 path = gtk_tree_path_new_from_indices (new_font_index, -1);
2809 if (gtk_tree_model_get_iter (priv->faces_model, &iter, path)) {
2813 gtk_tree_model_get (priv->faces_model, &iter, 0, &face_name, -1);
2815 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
2816 GINT_TO_POINTER(new_font_index)))
2817 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
2819 markup = g_strconcat ("<span font_family='", face_name, "'>Tt</span>", NULL);
2820 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
2822 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
2826 gtk_tree_path_free (path);
2829 gtk_widget_destroy (dialog);
2831 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
2836 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2839 ModestMsgEditWindowPrivate *priv = NULL;
2840 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2842 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2843 if (!priv->update_caption_visibility)
2846 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2848 gtk_widget_show (priv->cc_caption);
2850 gtk_widget_hide (priv->cc_caption);
2852 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2856 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2859 ModestMsgEditWindowPrivate *priv = NULL;
2860 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2862 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2863 if (!priv->update_caption_visibility)
2866 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2868 gtk_widget_show (priv->bcc_caption);
2870 gtk_widget_hide (priv->bcc_caption);
2872 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2876 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2877 ModestRecptEditor *editor)
2879 ModestMsgEditWindowPrivate *priv;
2881 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2882 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2884 /* we check for low-mem; in that case, show a warning, and don't allow
2885 * for the addressbook
2887 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2890 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2892 if (editor == NULL) {
2893 GtkWidget *view_focus;
2894 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2896 /* This code should be kept in sync with ModestRecptEditor. The
2897 textview inside the recpt editor is the one that really gets the
2898 focus. As it's inside a scrolled window, and this one inside the
2899 hbox recpt editor inherits from, we'll need to go up in the
2900 hierarchy to know if the text view is part of the recpt editor
2901 or if it's a different text entry */
2903 if (gtk_widget_get_parent (view_focus)) {
2904 GtkWidget *first_parent;
2906 first_parent = gtk_widget_get_parent (view_focus);
2907 if (gtk_widget_get_parent (first_parent) &&
2908 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2909 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2914 editor = MODEST_RECPT_EDITOR (priv->to_field);
2918 modest_address_book_select_addresses (editor);
2923 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2925 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2927 modest_msg_edit_window_open_addressbook (window, NULL);
2931 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2932 gboolean show_toolbar)
2934 ModestWindowPrivate *parent_priv;
2936 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2937 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2939 /* We can not just use the code of
2940 modest_msg_edit_window_setup_toolbar because it has a
2941 mixture of both initialization and creation code. */
2943 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2945 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2949 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2950 TnyHeaderFlags priority_flags)
2952 ModestMsgEditWindowPrivate *priv;
2953 ModestWindowPrivate *parent_priv;
2955 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2957 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2958 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2960 if (priv->priority_flags != priority_flags) {
2961 GtkAction *priority_action = NULL;
2963 priv->priority_flags = priority_flags;
2965 switch (priority_flags) {
2966 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2967 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2968 MODEST_HEADER_ICON_HIGH,
2969 HILDON_ICON_SIZE_SMALL);
2970 gtk_widget_show (priv->priority_icon);
2971 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2972 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2974 case TNY_HEADER_FLAG_LOW_PRIORITY:
2975 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon),
2976 MODEST_HEADER_ICON_LOW,
2977 HILDON_ICON_SIZE_SMALL);
2978 gtk_widget_show (priv->priority_icon);
2979 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2980 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2983 gtk_widget_hide (priv->priority_icon);
2984 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2985 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2988 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2989 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2991 gtk_widget_queue_resize (priv->subject_box);
2995 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2998 ModestMsgEditWindowPrivate *priv;
2999 ModestWindowPrivate *parent_priv;
3000 gint current_format;
3002 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3004 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
3005 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3007 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
3008 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
3010 if (current_format != file_format) {
3011 switch (file_format) {
3012 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
3013 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
3014 remove_tags (WP_TEXT_BUFFER (priv->text_buffer));
3016 case MODEST_FILE_FORMAT_PLAIN_TEXT:
3020 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
3021 response = gtk_dialog_run (GTK_DIALOG (dialog));
3022 gtk_widget_destroy (dialog);
3023 if (response == GTK_RESPONSE_OK) {
3024 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
3026 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatFormattedTextMenu"));
3027 modest_utils_toggle_action_set_active_block_notify (action, TRUE);
3032 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3033 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3034 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
3039 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
3042 ModestMsgEditWindowPrivate *priv;
3043 WPTextBufferFormat oldfmt, fmt;
3044 gint old_position = 0;
3048 GdkColor *color = NULL;
3049 gboolean bold, bold_set, italic, italic_set;
3050 gboolean underline, underline_set;
3051 gboolean strikethrough, strikethrough_set;
3052 gboolean position_set;
3053 gboolean font_size_set, font_set, color_set;
3056 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3057 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3059 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
3060 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(),
3061 GTK_WINDOW(dialog), GTK_WINDOW (window));
3063 /* First we get the currently selected font information */
3064 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
3066 switch (oldfmt.text_position) {
3067 case TEXT_POSITION_NORMAL:
3070 case TEXT_POSITION_SUPERSCRIPT:
3078 g_object_set (G_OBJECT (dialog),
3079 "bold", oldfmt.bold != FALSE,
3080 "bold-set", !oldfmt.cs.bold,
3081 "underline", oldfmt.underline != FALSE,
3082 "underline-set", !oldfmt.cs.underline,
3083 "italic", oldfmt.italic != FALSE,
3084 "italic-set", !oldfmt.cs.italic,
3085 "strikethrough", oldfmt.strikethrough != FALSE,
3086 "strikethrough-set", !oldfmt.cs.strikethrough,
3087 "color", &oldfmt.color,
3088 "color-set", !oldfmt.cs.color,
3089 "size", wp_font_size[oldfmt.font_size],
3090 "size-set", !oldfmt.cs.font_size,
3091 "position", old_position,
3092 "position-set", !oldfmt.cs.text_position,
3093 "family", wp_get_font_name (oldfmt.font),
3094 "family-set", !oldfmt.cs.font,
3097 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
3098 GTK_WINDOW (dialog), GTK_WINDOW (window));
3099 gtk_widget_show_all (dialog);
3100 priv->font_dialog = dialog;
3101 response = gtk_dialog_run (GTK_DIALOG (dialog));
3102 priv->font_dialog = NULL;
3103 if (response == GTK_RESPONSE_OK) {
3105 g_object_get( dialog,
3107 "bold-set", &bold_set,
3108 "underline", &underline,
3109 "underline-set", &underline_set,
3111 "italic-set", &italic_set,
3112 "strikethrough", &strikethrough,
3113 "strikethrough-set", &strikethrough_set,
3115 "color-set", &color_set,
3117 "size-set", &font_size_set,
3118 "family", &font_name,
3119 "family-set", &font_set,
3120 "position", &position,
3121 "position-set", &position_set,
3126 if (response == GTK_RESPONSE_OK) {
3127 memset(&fmt, 0, sizeof(fmt));
3133 fmt.italic = italic;
3134 fmt.cs.italic = TRUE;
3136 if (underline_set) {
3137 fmt.underline = underline;
3138 fmt.cs.underline = TRUE;
3140 if (strikethrough_set) {
3141 fmt.strikethrough = strikethrough;
3142 fmt.cs.strikethrough = TRUE;
3147 ? TEXT_POSITION_NORMAL
3148 : ( ( position == 1 )
3149 ? TEXT_POSITION_SUPERSCRIPT
3150 : TEXT_POSITION_SUBSCRIPT );
3151 fmt.cs.text_position = TRUE;
3152 fmt.font_size = oldfmt.font_size;
3156 fmt.cs.color = TRUE;
3159 fmt.font = wp_get_font_index(font_name,
3164 if (font_size_set) {
3165 fmt.cs.font_size = TRUE;
3166 fmt.font_size = wp_get_font_size_index(font_size, DEFAULT_FONT_SIZE);
3168 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
3169 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), window);
3171 gtk_widget_destroy (dialog);
3173 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
3177 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
3179 ModestMsgEditWindowPrivate *priv;
3181 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3182 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3184 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
3186 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3187 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3191 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
3193 ModestMsgEditWindowPrivate *priv;
3195 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3196 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3198 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
3200 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3201 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3206 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
3208 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3210 priv->can_undo = can_undo;
3214 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
3216 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3218 priv->can_redo = can_redo;
3222 modest_msg_edit_window_can_undo (ModestMsgEditWindow *window)
3224 ModestMsgEditWindowPrivate *priv;
3225 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3226 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3228 return priv->can_undo;
3232 modest_msg_edit_window_can_redo (ModestMsgEditWindow *window)
3234 ModestMsgEditWindowPrivate *priv;
3235 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3236 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3238 return priv->can_redo;
3243 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
3246 GtkTextIter match_start, match_end;
3248 if (image_id == NULL)
3251 gtk_text_buffer_get_start_iter (buffer, &iter);
3253 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
3254 GSList *tags = gtk_text_iter_get_tags (&match_start);
3256 for (node = tags; node != NULL; node = g_slist_next (node)) {
3257 GtkTextTag *tag = (GtkTextTag *) node->data;
3258 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
3259 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
3260 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
3262 offset = gtk_text_iter_get_offset (&match_start);
3263 gtk_text_buffer_delete (buffer, &match_start, &match_end);
3264 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
3268 gtk_text_iter_forward_char (&iter);
3273 message_is_empty (ModestMsgEditWindow *window)
3275 ModestMsgEditWindowPrivate *priv = NULL;
3277 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3278 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3280 /** TODO: Add wpeditor API to tell us if there is any _visible_ text,
3281 * so we can ignore markup.
3283 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
3286 count = gtk_text_buffer_get_char_count (buf);
3292 msg_body_focus (GtkWidget *focus,
3293 GdkEventFocus *event,
3297 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (userdata));
3298 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (userdata));
3299 modest_window_check_dimming_rules_group (MODEST_WINDOW (userdata), MODEST_DIMMING_RULES_CLIPBOARD);
3304 recpt_field_changed (GtkTextBuffer *buffer,
3305 ModestMsgEditWindow *editor)
3307 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3308 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3312 body_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor)
3314 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (editor));
3315 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (editor));
3319 modest_msg_edit_window_set_modified (ModestMsgEditWindow *editor,
3322 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3323 GtkTextBuffer *buffer;
3325 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3326 gtk_text_buffer_set_modified (buffer, modified);
3327 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3328 gtk_text_buffer_set_modified (buffer, modified);
3329 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3330 gtk_text_buffer_set_modified (buffer, modified);
3331 gtk_text_buffer_set_modified (priv->text_buffer, modified);
3335 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
3337 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
3338 const char *account_name;
3339 GtkTextBuffer *buffer;
3341 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
3342 if (gtk_text_buffer_get_modified (buffer))
3344 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
3345 if (gtk_text_buffer_get_modified (buffer))
3347 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
3348 if (gtk_text_buffer_get_modified (buffer))
3350 if (gtk_text_buffer_get_modified (priv->text_buffer))
3353 account_name = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3354 if (priv->original_mailbox) {
3355 if (!account_name || strcmp (account_name, priv->original_mailbox))
3357 } else if (!priv->original_account_name || strcmp(account_name, priv->original_account_name)) {
3368 modest_msg_edit_window_check_names (ModestMsgEditWindow *window, gboolean add_to_addressbook)
3370 ModestMsgEditWindowPrivate *priv = NULL;
3372 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3373 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3375 /* check if there's no recipient added */
3376 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
3377 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
3378 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
3379 /* no recipient contents, then select contacts */
3380 modest_msg_edit_window_open_addressbook (window, NULL);
3384 g_object_ref (window);
3385 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field), add_to_addressbook)) {
3386 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3387 g_object_unref (window);
3390 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field), add_to_addressbook)) {
3391 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->cc_field));
3392 g_object_unref (window);
3395 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field), add_to_addressbook)) {
3396 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->bcc_field));
3397 g_object_unref (window);
3401 if (!modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->cc_field)) &&
3402 !modest_recpt_editor_has_focus (MODEST_RECPT_EDITOR (priv->bcc_field)))
3403 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
3404 g_object_unref (window);
3411 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
3412 ModestMsgEditWindow *window)
3414 modest_msg_edit_window_offer_attach_file (window);
3418 modest_msg_edit_window_get_clipboard_text (ModestMsgEditWindow *win)
3420 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3422 return priv->clipboard_text;
3426 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
3428 ModestMsgEditWindow *window)
3430 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3431 GtkClipboard *selection_clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3434 /* It could happen that the window was already closed */
3435 if (!GTK_WIDGET_VISIBLE (window))
3438 g_object_ref (window);
3439 text = gtk_clipboard_wait_for_text (selection_clipboard);
3441 if (priv->clipboard_text != NULL) {
3442 g_free (priv->clipboard_text);
3444 priv->clipboard_text = text;
3446 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3448 g_object_unref (window);
3451 static gboolean clipboard_owner_change_idle (gpointer userdata)
3453 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
3454 ModestMsgEditWindowPrivate *priv;
3456 gdk_threads_enter ();
3457 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
3458 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3460 priv->clipboard_owner_idle = 0;
3461 modest_msg_edit_window_clipboard_owner_change (NULL, NULL, window);
3462 gdk_threads_leave ();
3468 modest_msg_edit_window_clipboard_owner_handle_change_in_idle (ModestMsgEditWindow *window)
3470 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3471 if (priv->clipboard_owner_idle == 0) {
3472 priv->clipboard_owner_idle = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
3473 clipboard_owner_change_idle,
3474 g_object_ref (window),
3480 subject_field_move_cursor (GtkEntry *entry,
3481 GtkMovementStep step,
3486 /* It could happen that the window was already closed */
3487 if (!GTK_WIDGET_VISIBLE (window))
3490 modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
3494 update_window_title (ModestMsgEditWindow *window)
3496 ModestMsgEditWindowPrivate *priv = NULL;
3497 const gchar *subject;
3499 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3500 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
3501 if (subject == NULL || subject[0] == '\0')
3502 subject = _("mail_va_new_email");
3504 gtk_window_set_title (GTK_WINDOW (window), subject);
3510 body_insert_text (GtkTextBuffer *buffer,
3511 GtkTextIter *location,
3514 ModestMsgEditWindow *window)
3516 GtkTextIter end_iter;
3519 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end_iter);
3521 offset = gtk_text_iter_get_offset (&end_iter);
3523 if (offset + len > MAX_BODY_LENGTH) {
3524 g_signal_stop_emission_by_name (G_OBJECT (buffer), "insert-text");
3525 if (offset < MAX_BODY_LENGTH)
3529 /* Prevent endless recursion */
3530 result = g_strndup (text, MAX_BODY_LENGTH - offset);
3531 g_signal_handlers_block_by_func (G_OBJECT (buffer), G_CALLBACK (body_insert_text), window);
3532 g_signal_emit_by_name (G_OBJECT (buffer), "insert-text", location,
3533 (gpointer) result, (gpointer) MAX_BODY_LENGTH - offset,
3535 g_signal_handlers_unblock_by_func (G_OBJECT (buffer), G_CALLBACK (body_insert_text), window);
3539 if (offset + len > MAX_BODY_LENGTH) {
3540 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3541 _CS("ckdg_ib_maximum_characters_reached"));
3546 subject_field_changed (GtkEditable *editable,
3547 ModestMsgEditWindow *window)
3549 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3550 update_window_title (window);
3551 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3552 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3553 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
3556 subject_field_insert_text (GtkEditable *editable,
3558 gint new_text_length,
3560 ModestMsgEditWindow *window)
3562 GString *result = g_string_new ("");
3564 gint result_len = 0;
3565 const gchar *entry_text = NULL;
3568 entry_text = gtk_entry_get_text (GTK_ENTRY (editable));
3569 old_length = g_utf8_strlen (entry_text, -1);
3571 for (current = new_text; current != NULL && *current != '\0'; current = g_utf8_next_char (current)) {
3572 gunichar c = g_utf8_get_char_validated (current, 8);
3573 /* Invalid unichar, stop */
3579 result = g_string_append_unichar (result, c);
3583 if (MIN (result_len, 1000) != g_utf8_strlen (new_text, 1000)) {
3584 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");
3587 /* Prevent endless recursion */
3588 g_signal_handlers_block_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3589 g_signal_emit_by_name (editable, "insert-text",
3590 (gpointer) result->str, (gpointer) result->len,
3591 (gpointer) position, (gpointer) window);
3592 g_signal_handlers_unblock_by_func(G_OBJECT(editable), G_CALLBACK(subject_field_insert_text), window);
3596 if (result_len + old_length > 1000) {
3597 hildon_banner_show_information (GTK_WIDGET (window), NULL,
3598 _CS("ckdg_ib_maximum_characters_reached"));
3600 g_string_free (result, TRUE);
3604 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
3607 ModestMsgEditWindowPrivate *priv = NULL;
3609 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3610 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3612 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
3615 gtk_widget_show_all (priv->find_toolbar);
3616 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
3618 gtk_widget_hide_all (priv->find_toolbar);
3619 gtk_widget_grab_focus (priv->msg_body);
3624 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
3626 GtkTextIter *match_start,
3627 GtkTextIter *match_end)
3629 GtkTextIter end_iter;
3630 gchar *str_casefold;
3633 gchar *range_casefold;
3636 gboolean result = FALSE;
3643 gtk_text_iter_forward_to_end (&end_iter);
3645 str_casefold = g_utf8_casefold (str, -1);
3646 str_chars_n = strlen (str);
3648 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
3649 range_casefold = g_utf8_casefold (range_text, -1);
3650 range_chars_n = strlen (range_casefold);
3652 if (range_chars_n < str_chars_n) {
3653 g_free (str_casefold);
3654 g_free (range_text);
3655 g_free (range_casefold);
3659 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
3660 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
3661 if (!g_utf8_collate (range_subtext, str_casefold)) {
3662 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
3664 if (!gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
3665 match_start, match_end, NULL)) {
3666 g_warning ("Matched string with collate, but not matched in model");
3668 g_free (found_text);
3670 g_free (range_subtext);
3674 g_free (str_casefold);
3675 g_free (range_text);
3676 g_free (range_casefold);
3683 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
3684 ModestMsgEditWindow *window)
3686 gchar *current_search = NULL;
3687 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3689 GtkTextIter selection_start, selection_end;
3690 GtkTextIter match_start, match_end;
3691 gboolean continue_search = FALSE;
3693 if (message_is_empty (window)) {
3694 g_free (priv->last_search);
3695 priv->last_search = NULL;
3696 hildon_banner_show_information (GTK_WIDGET (window), NULL, _("mail_ib_nothing_to_find"));
3700 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
3701 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
3702 g_free (current_search);
3703 g_free (priv->last_search);
3704 priv->last_search = NULL;
3705 /* Information banner about empty search */
3706 hildon_banner_show_information (NULL, NULL, _CS("ecdg_ib_find_rep_enter_text"));
3710 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
3711 continue_search = TRUE;
3713 g_free (priv->last_search);
3714 priv->last_search = g_strdup (current_search);
3717 if (continue_search) {
3718 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
3719 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
3720 &match_start, &match_end);
3722 hildon_banner_show_information (NULL, NULL, _HL("ckct_ib_find_search_complete"));
3724 GtkTextIter buffer_start;
3725 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
3726 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
3727 &match_start, &match_end);
3729 hildon_banner_show_information (NULL, NULL, _HL("ckct_ib_find_no_matches"));
3732 /* Mark as selected the string found in search */
3734 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
3735 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
3736 correct_scroll_without_drag_check (MODEST_MSG_EDIT_WINDOW (window), FALSE);
3738 g_free (priv->last_search);
3739 priv->last_search = NULL;
3741 g_free (current_search);
3745 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
3747 ModestMsgEditWindowPrivate *priv;
3749 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3754 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
3757 ModestMsgEditWindowPrivate *priv;
3759 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
3764 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
3765 ModestMsgEditWindow *window)
3767 modest_msg_edit_window_toggle_find_toolbar (window, FALSE);
3771 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
3774 ModestMsgEditWindowPrivate *priv;
3775 TnyHeader *header = NULL;
3777 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3778 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
3780 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3782 if (priv->draft_msg != NULL) {
3783 g_object_unref (priv->draft_msg);
3786 if (draft != NULL) {
3787 g_object_ref (draft);
3788 header = tny_msg_get_header (draft);
3789 if (priv->msg_uid) {
3790 g_free (priv->msg_uid);
3791 priv->msg_uid = NULL;
3793 priv->msg_uid = modest_tny_folder_get_header_unique_id (header);
3796 priv->draft_msg = draft;
3800 text_buffer_apply_tag (GtkTextBuffer *buffer, GtkTextTag *tag,
3801 GtkTextIter *start, GtkTextIter *end,
3804 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
3805 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (userdata);
3808 if (tag == NULL) return;
3809 g_object_get (G_OBJECT (tag), "name", &tag_name, NULL);
3810 if ((tag_name != NULL) && (g_str_has_prefix (tag_name, "image-tag-replace-"))) {
3811 replace_with_images (window, priv->images);
3816 modest_msg_edit_window_add_part (ModestMsgEditWindow *window,
3819 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3821 g_return_if_fail (TNY_IS_MIME_PART (part));
3822 tny_list_prepend (priv->attachments, (GObject *) part);
3823 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), part, TRUE, 0);
3824 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
3825 gtk_widget_show_all (priv->attachments_caption);
3826 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
3830 modest_msg_edit_window_get_message_uid (ModestMsgEditWindow *window)
3832 ModestMsgEditWindowPrivate *priv;
3834 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), NULL);
3835 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
3837 return priv->msg_uid;
3841 modest_msg_edit_window_get_child_widget (ModestMsgEditWindow *win,
3842 ModestMsgEditWindowWidgetType widget_type)
3844 ModestMsgEditWindowPrivate *priv;
3846 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (win), NULL);
3847 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (win);
3849 switch (widget_type) {
3850 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BODY:
3851 return priv->msg_body;
3853 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_TO:
3854 return priv->to_field;
3856 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_CC:
3857 return priv->cc_field;
3859 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_BCC:
3860 return priv->bcc_field;
3862 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_SUBJECT:
3863 return priv->subject_field;
3865 case MODEST_MSG_EDIT_WINDOW_WIDGET_TYPE_ATTACHMENTS:
3866 return priv->attachments_view;
3874 remove_tags (WPTextBuffer *buffer)
3876 GtkTextIter start, end;
3878 gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (buffer), &start);
3879 gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (buffer), &end);
3881 gtk_text_buffer_remove_all_tags (GTK_TEXT_BUFFER (buffer), &start, &end);
3885 on_account_removed (TnyAccountStore *account_store,
3886 TnyAccount *account,
3889 /* Do nothing if it's a store account, because we use the
3890 transport to send the messages */
3891 if (tny_account_get_account_type(account) == TNY_ACCOUNT_TYPE_TRANSPORT) {
3892 const gchar *parent_acc = NULL;
3893 const gchar *our_acc = NULL;
3895 our_acc = modest_window_get_active_account (MODEST_WINDOW (user_data));
3896 parent_acc = modest_tny_account_get_parent_modest_account_name_for_server_account (account);
3897 /* Close this window if I'm showing a message of the removed account */
3898 if (strcmp (parent_acc, our_acc) == 0)
3899 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (user_data));
3903 static void update_signature (ModestMsgEditWindow *self,
3904 const gchar *old_account,
3905 const gchar *new_account)
3907 ModestMsgEditWindowPrivate *priv;
3908 gboolean has_old_signature, has_new_signature;
3910 GtkTextIter match_start, match_end;
3911 ModestAccountMgr *mgr;
3913 gchar *full_signature;
3915 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
3917 gtk_text_buffer_begin_user_action (priv->text_buffer);
3919 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
3920 mgr = modest_runtime_get_account_mgr ();
3924 signature = modest_account_mgr_get_signature_from_recipient (mgr, old_account, &has_old_signature);
3925 if (has_old_signature) {
3926 full_signature = g_strconcat ("\n--\n", signature, NULL);
3927 if (gtk_text_iter_forward_search (&iter, full_signature, 0, &match_start, &match_end, NULL)) {
3928 gtk_text_buffer_delete (priv->text_buffer, &match_start, &match_end);
3930 } else if (gtk_text_iter_forward_search (&iter, _("mcen_ia_editor_original_message"), 0,
3931 &match_start, &match_end, NULL)) {
3934 g_free (full_signature);
3939 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3940 signature = modest_account_mgr_get_signature_from_recipient (mgr, new_account, &has_new_signature);
3941 if (has_new_signature) {
3942 full_signature = g_strconcat ("\n--\n", signature, NULL);
3943 gtk_text_buffer_insert (priv->text_buffer, &iter, full_signature, -1);
3944 g_free (full_signature);
3947 gtk_text_buffer_end_user_action (priv->text_buffer);
3951 from_field_changed (HildonPickerButton *button,
3952 ModestMsgEditWindow *self)
3954 ModestMsgEditWindowPrivate *priv;
3955 gchar *old_account, *new_account;
3957 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
3959 old_account = priv->last_from_account;
3960 priv->last_from_account = modest_selector_picker_get_active_id (MODEST_SELECTOR_PICKER (priv->from_field));
3961 new_account = priv->last_from_account;
3963 update_signature (self, old_account, new_account);
3967 typedef struct _MessageSettingsHelper {
3968 ModestMsgEditWindow *window;
3969 GSList *priority_group;
3970 GSList *format_group;
3971 GtkToggleButton *current_priority;
3972 GtkToggleButton *current_format;
3973 } MessageSettingsHelper;
3976 on_priority_toggle (GtkToggleButton *button,
3977 MessageSettingsHelper *helper)
3980 ModestMsgEditWindowPrivate *priv;
3982 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (helper->window);
3983 if (gtk_toggle_button_get_active (button)) {
3985 for (node = helper->priority_group; node != NULL; node = g_slist_next (node)) {
3986 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3987 if ((node_button != button) &&
3988 gtk_toggle_button_get_active (node_button)) {
3989 gtk_toggle_button_set_active (node_button, FALSE);
3992 helper->current_priority = button;
3994 gboolean found = FALSE;
3995 /* If no one is active, activate it again */
3996 for (node = helper->priority_group; node != NULL; node = g_slist_next (node)) {
3997 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
3998 if (gtk_toggle_button_get_active (node_button)) {
4004 gtk_toggle_button_set_active (button, TRUE);
4010 on_format_toggle (GtkToggleButton *button,
4011 MessageSettingsHelper *helper)
4014 ModestMsgEditWindowPrivate *priv;
4016 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (helper->window);
4017 if (gtk_toggle_button_get_active (button)) {
4019 for (node = helper->format_group; node != NULL; node = g_slist_next (node)) {
4020 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
4021 if ((node_button != button) &&
4022 gtk_toggle_button_get_active (node_button)) {
4023 gtk_toggle_button_set_active (node_button, FALSE);
4026 helper->current_format = button;
4028 gboolean found = FALSE;
4029 /* If no one is active, activate it again */
4030 for (node = helper->format_group; node != NULL; node = g_slist_next (node)) {
4031 GtkToggleButton *node_button = (GtkToggleButton *) node->data;
4032 if (gtk_toggle_button_get_active (node_button)) {
4038 gtk_toggle_button_set_active (button, TRUE);
4045 modest_msg_edit_window_show_msg_settings_dialog (ModestMsgEditWindow *window)
4050 GtkWidget *priority_hbox;
4051 GtkWidget *high_toggle, *medium_toggle, *low_toggle;
4052 GtkWidget *captioned;
4053 GtkSizeGroup *title_sizegroup, *value_sizegroup;
4054 GtkWidget *format_hbox;
4055 GtkWidget *html_toggle, *text_toggle;
4056 ModestMsgEditWindowPrivate *priv;
4057 MessageSettingsHelper helper = {0,};
4059 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4060 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
4061 helper.window = window;
4062 helper.priority_group = NULL;
4063 helper.format_group = NULL;
4065 title_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4066 value_sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4068 dialog = gtk_dialog_new_with_buttons (_("mcen_me_message_settings"), NULL,
4069 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
4070 _HL("wdgt_bd_done"), GTK_RESPONSE_ACCEPT, NULL);
4071 vbox = gtk_vbox_new (FALSE, 0);
4072 align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
4073 gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, MODEST_MARGIN_DOUBLE, MODEST_MARGIN_DOUBLE, 0);
4074 gtk_container_add (GTK_CONTAINER (align), vbox);
4075 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), align);
4076 gtk_widget_show (align);
4077 gtk_widget_show (vbox);
4079 /* Priority toggles */
4080 priority_hbox = gtk_hbox_new (TRUE, 0);
4081 high_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4082 gtk_button_set_label (GTK_BUTTON (high_toggle), _("mcen_me_editor_priority_high"));
4083 helper.priority_group = g_slist_prepend (helper.priority_group, high_toggle);
4084 g_object_set_data (G_OBJECT (high_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_HIGH_PRIORITY));
4085 medium_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4086 gtk_button_set_label (GTK_BUTTON (medium_toggle), _("mcen_me_editor_priority_normal"));
4087 helper.priority_group = g_slist_prepend (helper.priority_group, medium_toggle);
4088 g_object_set_data (G_OBJECT (medium_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_NORMAL_PRIORITY));
4089 low_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4090 gtk_button_set_label (GTK_BUTTON (low_toggle), _("mcen_me_editor_priority_low"));
4091 helper.priority_group = g_slist_prepend (helper.priority_group, low_toggle);
4092 g_object_set_data (G_OBJECT (low_toggle), "priority", GINT_TO_POINTER (TNY_HEADER_FLAG_LOW_PRIORITY));
4093 gtk_box_pack_start (GTK_BOX (priority_hbox), low_toggle, TRUE, TRUE, 0);
4094 gtk_box_pack_start (GTK_BOX (priority_hbox), medium_toggle, TRUE, TRUE, 0);
4095 gtk_box_pack_start (GTK_BOX (priority_hbox), high_toggle, TRUE, TRUE, 0);
4096 gtk_widget_show_all (priority_hbox);
4097 captioned = modest_maemo_utils_create_captioned (title_sizegroup, value_sizegroup,
4098 _("mcen_me_editor_message_priority"), FALSE, priority_hbox);
4099 gtk_widget_show (captioned);
4100 gtk_box_pack_start (GTK_BOX (vbox), captioned, FALSE, FALSE, 0);
4102 /* format toggles */
4103 format_hbox = gtk_hbox_new (TRUE, 0);
4104 html_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4105 gtk_button_set_label (GTK_BUTTON (html_toggle), _("mcen_me_editor_formatted_text"));
4106 helper.format_group = g_slist_prepend (helper.format_group, html_toggle);
4107 g_object_set_data (G_OBJECT (html_toggle), "format", GINT_TO_POINTER (MODEST_MSG_EDIT_FORMAT_HTML));
4108 g_object_set_data (G_OBJECT (html_toggle), "file-format", GINT_TO_POINTER (MODEST_FILE_FORMAT_FORMATTED_TEXT));
4109 text_toggle = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
4110 gtk_button_set_label (GTK_BUTTON (text_toggle), _("mcen_me_editor_plain_text"));
4111 helper.format_group = g_slist_prepend (helper.format_group, text_toggle);
4112 g_object_set_data (G_OBJECT (text_toggle), "format", GINT_TO_POINTER (MODEST_MSG_EDIT_FORMAT_TEXT));
4113 g_object_set_data (G_OBJECT (text_toggle), "file-format", GINT_TO_POINTER (MODEST_FILE_FORMAT_PLAIN_TEXT));
4114 gtk_box_pack_start (GTK_BOX (format_hbox), html_toggle, TRUE, TRUE, 0);
4115 gtk_box_pack_start (GTK_BOX (format_hbox), text_toggle, TRUE, TRUE, 0);
4116 gtk_widget_show_all (format_hbox);
4117 gtk_widget_show (format_hbox);
4118 gtk_box_pack_start (GTK_BOX (vbox), format_hbox, FALSE, FALSE, 0);
4121 g_object_unref (title_sizegroup);
4122 g_object_unref (value_sizegroup);
4124 /* Set current values */
4125 switch (priv->priority_flags) {
4126 case TNY_HEADER_FLAG_HIGH_PRIORITY:
4127 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (high_toggle), TRUE);
4128 helper.current_priority = GTK_TOGGLE_BUTTON (high_toggle);
4130 case TNY_HEADER_FLAG_LOW_PRIORITY:
4131 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (low_toggle), TRUE);
4132 helper.current_priority = GTK_TOGGLE_BUTTON (low_toggle);
4135 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (medium_toggle), TRUE);
4136 helper.current_priority = GTK_TOGGLE_BUTTON (medium_toggle);
4140 switch (modest_msg_edit_window_get_format (window)) {
4141 case MODEST_MSG_EDIT_FORMAT_TEXT:
4142 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (text_toggle), TRUE);
4143 helper.current_format = GTK_TOGGLE_BUTTON (text_toggle);
4145 case MODEST_MSG_EDIT_FORMAT_HTML:
4147 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (html_toggle), TRUE);
4148 helper.current_format = GTK_TOGGLE_BUTTON (html_toggle);
4152 /* Signal connects */
4153 g_signal_connect (G_OBJECT (high_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4154 g_signal_connect (G_OBJECT (medium_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4155 g_signal_connect (G_OBJECT (low_toggle), "toggled", G_CALLBACK (on_priority_toggle), &helper);
4156 g_signal_connect (G_OBJECT (html_toggle), "toggled", G_CALLBACK (on_format_toggle), &helper);
4157 g_signal_connect (G_OBJECT (text_toggle), "toggled", G_CALLBACK (on_format_toggle), &helper);
4159 /* Save settings if the user clicked on done */
4160 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
4161 TnyHeaderFlags flags;
4162 ModestMsgEditFormat old_format, new_format;
4164 /* Set priority flags */
4165 flags = (TnyHeaderFlags) g_object_get_data (G_OBJECT (helper.current_priority), "priority");
4166 if (priv->priority_flags != flags)
4167 modest_msg_edit_window_set_priority_flags (window, flags);
4169 /* Set edit format */
4170 old_format = modest_msg_edit_window_get_format (window);
4171 new_format = (ModestMsgEditFormat) g_object_get_data (G_OBJECT (helper.current_format), "format");
4172 if (old_format != new_format) {
4173 gint file_format = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (helper.current_format), "file-format"));
4174 modest_msg_edit_window_set_file_format (window, file_format);
4178 gtk_widget_destroy (dialog);
4179 g_slist_free (helper.priority_group);
4183 on_message_settings (GtkAction *action,
4184 ModestMsgEditWindow *window)
4186 modest_msg_edit_window_show_msg_settings_dialog (window);
4190 on_cc_button_toggled (HildonCheckButton *button,
4191 ModestMsgEditWindow *window)
4193 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
4195 modest_msg_edit_window_show_cc (MODEST_MSG_EDIT_WINDOW (window),
4196 hildon_check_button_get_active (button));
4200 on_bcc_button_toggled (HildonCheckButton *button,
4201 ModestMsgEditWindow *window)
4203 g_return_if_fail (MODEST_MSG_EDIT_WINDOW (window));
4205 modest_msg_edit_window_show_bcc (MODEST_MSG_EDIT_WINDOW (window),
4206 hildon_check_button_get_active (button));
4210 setup_menu (ModestMsgEditWindow *self)
4212 ModestMsgEditWindowPrivate *priv = NULL;
4214 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(self));
4216 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
4218 /* Settings menu buttons */
4219 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_editor_checknames"), NULL,
4220 APP_MENU_CALLBACK (modest_ui_actions_on_check_names),
4222 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_undo"), "<Ctrl>z",
4223 APP_MENU_CALLBACK (modest_ui_actions_on_undo),
4224 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_undo));
4226 priv->cc_button = hildon_check_button_new (0);
4227 gtk_button_set_label (GTK_BUTTON (priv->cc_button), _("mcen_me_editor_showcc"));
4228 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->cc_button),
4230 modest_hildon2_window_add_button_to_menu (MODEST_HILDON2_WINDOW (self), GTK_BUTTON (priv->cc_button),
4232 g_signal_connect (G_OBJECT (priv->cc_button), "toggled",
4233 G_CALLBACK (on_cc_button_toggled), (gpointer) self);
4234 gtk_button_set_alignment (GTK_BUTTON (priv->cc_button), 0.5, 0.5);
4235 gtk_button_set_alignment (GTK_BUTTON (priv->cc_button), 0.5, 0.5);
4237 priv->bcc_button = hildon_check_button_new (0);
4238 gtk_button_set_label (GTK_BUTTON (priv->bcc_button), _("mcen_me_editor_showbcc"));
4239 hildon_check_button_set_active (HILDON_CHECK_BUTTON (priv->bcc_button),
4241 modest_hildon2_window_add_button_to_menu (MODEST_HILDON2_WINDOW (self), GTK_BUTTON (priv->bcc_button),
4243 g_signal_connect (G_OBJECT (priv->bcc_button), "toggled",
4244 G_CALLBACK (on_bcc_button_toggled), (gpointer) self);
4245 gtk_button_set_alignment (GTK_BUTTON (priv->bcc_button), 0.5, 0.5);
4246 gtk_button_set_alignment (GTK_BUTTON (priv->bcc_button), 0.5, 0.5);
4248 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_editor_attach_inlineimage"), NULL,
4249 APP_MENU_CALLBACK (modest_ui_actions_on_insert_image),
4250 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_set_style));
4251 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_inbox_remove_attachments"), NULL,
4252 APP_MENU_CALLBACK (modest_ui_actions_on_remove_attachments),
4253 MODEST_DIMMING_CALLBACK (modest_ui_dimming_rules_on_editor_remove_attachment));
4254 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_message_settings"), NULL,
4255 APP_MENU_CALLBACK (on_message_settings),
4257 modest_hildon2_window_add_to_menu (MODEST_HILDON2_WINDOW (self), _("mcen_me_viewer_find"), "<Ctrl>f",
4258 APP_MENU_CALLBACK (modest_ui_actions_on_toggle_find_in_page),
4263 _create_addressbook_box (GtkSizeGroup *title_size_group, GtkSizeGroup *value_size_group,
4264 const gchar *label, GtkWidget *control)
4266 GtkWidget *abook_button;
4270 box = gtk_hbox_new (FALSE, 0);
4272 align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
4273 gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 0, MODEST_MARGIN_DEFAULT);
4275 abook_button = hildon_gtk_button_new (HILDON_SIZE_FINGER_HEIGHT);
4276 gtk_button_set_label (GTK_BUTTON (abook_button), label);
4278 gtk_container_add (GTK_CONTAINER (align), abook_button);
4279 gtk_box_pack_start (GTK_BOX (box), align, FALSE, FALSE, 0);
4280 gtk_box_pack_start (GTK_BOX (box), control, TRUE, TRUE, 0);
4281 if (title_size_group)
4282 gtk_size_group_add_widget (title_size_group, abook_button);
4283 if (value_size_group)
4284 gtk_size_group_add_widget (value_size_group, control);