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>
41 #include <modest-account-mgr.h>
42 #include <modest-account-mgr-helpers.h>
44 #include <widgets/modest-msg-edit-window.h>
45 #include <widgets/modest-combo-box.h>
46 #include <widgets/modest-recpt-editor.h>
47 #include <widgets/modest-attachments-view.h>
49 #include <modest-runtime.h>
51 #include "modest-platform.h"
52 #include "modest-icon-names.h"
53 #include "modest-widget-memory.h"
54 #include "modest-window-priv.h"
55 #include "modest-mail-operation.h"
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-tny-folder.h"
59 #include "modest-address-book.h"
60 #include "modest-text-utils.h"
61 #include <tny-simple-list.h>
62 #include <wptextview.h>
63 #include <wptextbuffer.h>
64 #include "modest-scroll-area.h"
66 #include "modest-hildon-includes.h"
67 #ifdef MODEST_HAVE_HILDON0_WIDGETS
68 #include <hildon-widgets/hildon-color-chooser.h>
70 #include "widgets/modest-msg-edit-window-ui.h"
71 #ifdef MODEST_HAVE_HILDON0_WIDGETS
72 #include <libgnomevfs/gnome-vfs-mime-utils.h>
74 #include <libgnomevfs/gnome-vfs-mime.h>
76 #include "modest-maemo-utils.h"
79 #define DEFAULT_FONT_SIZE 3
80 #define DEFAULT_FONT 2
81 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
82 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
83 #define DEFAULT_MAIN_VBOX_SPACING 6
84 #define SUBJECT_MAX_LENGTH 1000
85 #define IMAGE_MAX_WIDTH 640
86 #define DEFAULT_FONT_SCALE 1.5
88 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
89 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
90 static void modest_msg_edit_window_finalize (GObject *obj);
92 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
93 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
94 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
95 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
96 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
97 static void reset_modified (ModestMsgEditWindow *editor);
99 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
100 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
101 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
102 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
103 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
104 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
105 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
107 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
109 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
111 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
112 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
113 GdkEventWindowState *event,
115 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
116 ModestRecptEditor *editor);
117 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
118 ModestMsgEditWindow *window);
120 /* ModestWindow methods implementation */
121 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
122 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
123 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
124 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
125 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
126 gboolean show_toolbar);
127 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
129 ModestMsgEditWindow *window);
130 static void update_window_title (ModestMsgEditWindow *window);
131 static void update_dimmed (ModestMsgEditWindow *window);
132 static void update_paste_dimming (ModestMsgEditWindow *window);
133 static void update_select_all_dimming (ModestMsgEditWindow *window);
134 static void update_zoom_dimming (ModestMsgEditWindow *window);
137 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
138 ModestMsgEditWindow *window);
139 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
140 ModestMsgEditWindow *window);
141 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
143 GtkTextIter *match_start,
144 GtkTextIter *match_end);
148 /* static gboolean */
149 /* on_key_pressed (GtkWidget *self, */
150 /* GdkEventKey *event, */
151 /* gpointer user_data); */
153 static void edit_menu_activated (GtkAction *action,
155 static void view_menu_activated (GtkAction *action,
158 /* list my signals */
165 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
166 struct _ModestMsgEditWindowPrivate {
168 GtkWidget *header_box;
170 ModestPairList *from_field_protos;
171 GtkWidget *from_field;
175 GtkWidget *bcc_field;
176 GtkWidget *subject_field;
177 GtkWidget *attachments_view;
178 GtkWidget *priority_icon;
179 GtkWidget *add_attachment_button;
181 GtkWidget *cc_caption;
182 GtkWidget *bcc_caption;
183 GtkWidget *attachments_caption;
185 GtkTextBuffer *text_buffer;
187 GtkWidget *font_size_toolitem;
188 GtkWidget *font_face_toolitem;
189 GtkWidget *font_color_button;
190 GSList *font_items_group;
191 GtkWidget *font_tool_button_label;
192 GSList *size_items_group;
193 GtkWidget *size_tool_button_label;
195 GtkWidget *find_toolbar;
199 GtkWidget *scroll_area;
204 TnyHeaderFlags priority_flags;
208 gulong clipboard_change_handler_id;
214 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
215 MODEST_TYPE_MSG_EDIT_WINDOW, \
216 ModestMsgEditWindowPrivate))
218 static GtkWindowClass *parent_class = NULL;
220 /* uncomment the following if you have defined any signals */
221 /* static guint signals[LAST_SIGNAL] = {0}; */
224 modest_msg_edit_window_get_type (void)
226 static GType my_type = 0;
228 static const GTypeInfo my_info = {
229 sizeof(ModestMsgEditWindowClass),
230 NULL, /* base init */
231 NULL, /* base finalize */
232 (GClassInitFunc) modest_msg_edit_window_class_init,
233 NULL, /* class finalize */
234 NULL, /* class data */
235 sizeof(ModestMsgEditWindow),
237 (GInstanceInitFunc) modest_msg_edit_window_init,
240 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
241 "ModestMsgEditWindow",
244 wp_text_buffer_library_init ();
250 save_state (ModestWindow *self)
252 modest_widget_memory_save (modest_runtime_get_conf(),
253 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
258 restore_settings (ModestMsgEditWindow *self)
260 modest_widget_memory_restore (modest_runtime_get_conf(),
261 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
266 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
268 GObjectClass *gobject_class;
269 ModestWindowClass *modest_window_class;
270 gobject_class = (GObjectClass*) klass;
271 modest_window_class = (ModestWindowClass*) klass;
273 parent_class = g_type_class_peek_parent (klass);
274 gobject_class->finalize = modest_msg_edit_window_finalize;
276 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
277 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
278 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
279 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
280 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
281 modest_window_class->save_state_func = save_state;
283 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
289 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
291 ModestMsgEditWindowPrivate *priv;
292 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
294 priv->msg_body = NULL;
295 priv->from_field = NULL;
296 priv->to_field = NULL;
297 priv->cc_field = NULL;
298 priv->bcc_field = NULL;
299 priv->subject_field = NULL;
300 priv->attachments = NULL;
302 priv->zoom_level = 1.0;
304 priv->cc_caption = NULL;
305 priv->bcc_caption = NULL;
307 priv->priority_flags = 0;
309 priv->find_toolbar = NULL;
310 priv->last_search = NULL;
312 priv->draft_msg = NULL;
313 priv->clipboard_change_handler_id = 0;
318 /* FIXME: this is a dup from the one in gtk/ */
321 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
323 static ModestPairList*
324 get_transports (void)
326 GSList *transports = NULL;
328 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
329 GSList *accounts = modest_account_mgr_account_names (account_mgr,
330 TRUE /* only enabled accounts. */);
332 GSList *cursor = accounts;
334 gchar *account_name = cursor->data;
335 gchar *from_string = NULL;
337 from_string = modest_account_mgr_get_from_string (account_mgr,
341 if (from_string && account_name) {
342 gchar *name = account_name;
343 ModestPair *pair = modest_pair_new ((gpointer) name,
344 (gpointer) from_string , TRUE);
345 transports = g_slist_prepend (transports, pair);
348 cursor = cursor->next;
350 g_slist_free (accounts); /* only free the accounts, not the elements,
351 * because they are used in the pairlist */
357 init_window (ModestMsgEditWindow *obj)
359 GtkWidget *from_caption, *to_caption, *subject_caption;
360 GtkWidget *main_vbox;
361 ModestMsgEditWindowPrivate *priv;
363 GtkSizeGroup *size_group;
365 GtkWidget *subject_box;
366 GtkWidget *attachment_icon;
367 GtkWidget *window_box;
369 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
371 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
373 /* Note: This ModestPairList* must exist for as long as the combo
374 * that uses it, because the ModestComboBox uses the ID opaquely,
375 * so it can't know how to manage its memory. */
376 priv->from_field_protos = get_transports ();
378 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
380 priv->to_field = modest_recpt_editor_new ();
381 priv->cc_field = modest_recpt_editor_new ();
382 priv->bcc_field = modest_recpt_editor_new ();
383 subject_box = gtk_hbox_new (FALSE, 0);
384 priv->priority_icon = gtk_image_new ();
385 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
386 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
387 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
388 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
389 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
390 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
391 priv->add_attachment_button = gtk_button_new ();
392 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
393 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
394 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
395 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
396 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
397 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
398 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
399 priv->attachments_view = modest_attachments_view_new (NULL);
401 priv->header_box = gtk_vbox_new (FALSE, 0);
403 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
404 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
405 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
406 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
407 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
408 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
409 g_object_unref (size_group);
411 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
412 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
413 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
414 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
415 gtk_size_group_add_widget (size_group, priv->subject_field);
416 gtk_size_group_add_widget (size_group, priv->attachments_view);
417 g_object_unref (size_group);
419 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
420 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
421 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
422 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
423 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
424 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
425 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
428 priv->msg_body = wp_text_view_new ();
429 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
430 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
431 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
432 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
433 #if (GTK_MINOR_VERSION >= 10)
434 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
435 gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
437 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
439 priv->find_toolbar = hildon_find_toolbar_new (NULL);
440 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
442 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
444 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
445 G_CALLBACK (text_buffer_refresh_attributes), obj);
446 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
447 G_CALLBACK (text_buffer_delete_range), obj);
448 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
449 G_CALLBACK (text_buffer_can_undo), obj);
450 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
451 G_CALLBACK (text_buffer_can_redo), obj);
452 g_signal_connect (G_OBJECT (obj), "window-state-event",
453 G_CALLBACK (modest_msg_edit_window_window_state_event),
455 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
456 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
457 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
458 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
459 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
460 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
462 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
463 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
465 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
466 G_CALLBACK (msg_body_focus), obj);
467 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
468 G_CALLBACK (msg_body_focus), obj);
469 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
470 "changed", G_CALLBACK (recpt_field_changed), obj);
471 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
472 "changed", G_CALLBACK (recpt_field_changed), obj);
473 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
474 "changed", G_CALLBACK (recpt_field_changed), obj);
475 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
476 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
478 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
479 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
481 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
482 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
483 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
484 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->scroll), TRUE);
486 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
488 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
489 frame = gtk_frame_new (NULL);
490 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
492 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
493 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
494 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
496 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
497 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
498 gtk_widget_hide (priv->cc_caption);
500 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
501 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
502 gtk_widget_hide (priv->bcc_caption);
505 window_box = gtk_vbox_new (FALSE, 0);
506 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
507 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
508 gtk_container_add (GTK_CONTAINER(obj), window_box);
509 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
510 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
513 TODO: scroll_area was never instantiated.
514 Stop building without warnings-as-errors. murrayc.
515 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
516 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
519 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
520 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
526 modest_msg_edit_window_finalize (GObject *obj)
528 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
530 if (priv->clipboard_change_handler_id > 0) {
531 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
532 priv->clipboard_change_handler_id = 0;
535 if (priv->draft_msg != NULL) {
536 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
537 if (TNY_IS_HEADER (header)) {
538 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
539 modest_window_mgr_unregister_header (mgr, header);
541 g_object_unref (priv->draft_msg);
542 priv->draft_msg = NULL;
545 /* This had to stay alive for as long as the combobox that used it: */
546 modest_pair_list_free (priv->from_field_protos);
548 G_OBJECT_CLASS(parent_class)->finalize (obj);
552 menubar_to_menu (GtkUIManager *ui_manager)
554 GtkWidget *main_menu;
558 /* Create new main menu */
559 main_menu = gtk_menu_new();
561 /* Get the menubar from the UI manager */
562 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
564 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
568 menu = GTK_WIDGET (iter->data);
569 gtk_widget_reparent(menu, main_menu);
571 iter = g_list_next (iter);
578 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
581 const gchar *to, *cc, *bcc, *subject;
583 ModestMsgEditWindowPrivate *priv;
585 TnyHeaderFlags priority_flags;
586 TnyFolder *msg_folder;
588 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
589 g_return_if_fail (TNY_IS_MSG (msg));
591 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
593 header = tny_msg_get_header (msg);
594 to = tny_header_get_to (header);
595 cc = tny_header_get_cc (header);
596 bcc = tny_header_get_bcc (header);
597 subject = tny_header_get_subject (header);
598 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
601 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
603 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
604 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
605 gtk_widget_show (priv->cc_caption);
606 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
607 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
608 gtk_widget_hide (priv->cc_caption);
611 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
612 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
613 gtk_widget_show (priv->bcc_caption);
614 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
615 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
616 gtk_widget_hide (priv->bcc_caption);
619 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
620 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
623 update_window_title (self);
625 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
626 body = modest_tny_msg_get_body (msg, TRUE);
628 if ((body == NULL)||(body[0] == '\0')) {
630 body = modest_text_utils_convert_to_html ("");
632 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
633 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
636 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
639 /* Get the default format required from configuration */
640 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
641 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
644 /* Set the default focus depending on having already a To: field or not */
645 if ((!to)||(*to == '\0')) {
646 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
648 gtk_widget_grab_focus (priv->msg_body);
651 /* TODO: lower priority, select in the From: combo to the
652 value that comes from msg <- not sure, should it be
655 /* Add attachments to the view */
656 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
657 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
658 if (priv->attachments == NULL) {
659 gtk_widget_hide (priv->attachments_caption);
661 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
662 gtk_widget_show_all (priv->attachments_caption);
665 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
666 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
668 reset_modified (self);
670 update_dimmed (self);
671 text_buffer_can_undo (priv->text_buffer, FALSE, self);
672 text_buffer_can_redo (priv->text_buffer, FALSE, self);
674 /* we should set a reference to the incoming message if it is a draft */
675 msg_folder = tny_msg_get_folder (msg);
677 if (modest_tny_folder_is_local_folder (msg_folder) &&
678 modest_tny_folder_get_local_folder_type (msg_folder) == TNY_FOLDER_TYPE_DRAFTS)
679 priv->draft_msg = g_object_ref(msg);
680 g_object_unref (msg_folder);
685 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
688 GList *item_children, *node;
689 GtkWidget *bin_child;
691 bin_child = gtk_bin_get_child (GTK_BIN(item));
693 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
695 for (node = item_children; node != NULL; node = g_list_next (node)) {
696 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
697 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
700 g_list_free (item_children);
704 menu_tool_button_dont_expand (GtkMenuToolButton *item)
707 GList *item_children, *node;
709 box = gtk_bin_get_child (GTK_BIN (item));
710 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
711 item_children = gtk_container_get_children (GTK_CONTAINER (box));
713 for (node = item_children; node != NULL; node = g_list_next (node)) {
714 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
715 if (GTK_IS_TOGGLE_BUTTON (node->data))
716 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
717 else if (GTK_IS_BUTTON (node->data))
718 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
720 g_list_free (item_children);
725 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
727 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
728 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
729 GtkWidget *placeholder;
730 GtkWidget *tool_item;
735 GtkWidget *sizes_menu;
736 GtkWidget *fonts_menu;
737 GSList *radio_group = NULL;
742 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
743 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
745 /* should we hide the toolbar? */
746 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
747 gtk_widget_hide (parent_priv->toolbar);
749 /* Font color placeholder */
750 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
751 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
754 tool_item = GTK_WIDGET (gtk_tool_item_new ());
755 priv->font_color_button = hildon_color_button_new ();
756 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
757 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
758 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
759 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
760 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
761 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
762 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
764 /* Font size and face placeholder */
765 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
766 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
768 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
769 priv->size_tool_button_label = gtk_label_new (NULL);
770 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
771 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
772 size_text,"</span>", NULL);
773 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
775 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
776 sizes_menu = gtk_menu_new ();
777 priv->size_items_group = NULL;
779 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
780 GtkWidget *size_menu_item;
782 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
783 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
784 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
785 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
786 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
787 gtk_widget_show (size_menu_item);
789 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
793 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
794 GtkWidget *item = (GtkWidget *) node->data;
795 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
799 priv->size_items_group = g_slist_reverse (priv->size_items_group);
800 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
801 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
802 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
803 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
804 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
805 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
806 priv->font_size_toolitem = tool_item;
809 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
810 priv->font_tool_button_label = gtk_label_new (NULL);
811 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
812 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
814 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
815 fonts_menu = gtk_menu_new ();
816 priv->font_items_group = NULL;
818 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
819 GtkWidget *font_menu_item;
820 GtkWidget *child_label;
822 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
823 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
824 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
825 wp_get_font_name (font_index), "</span>", NULL);
826 gtk_label_set_markup (GTK_LABEL (child_label), markup);
829 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
830 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
831 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
832 gtk_widget_show (font_menu_item);
834 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
837 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
838 GtkWidget *item = (GtkWidget *) node->data;
839 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
842 priv->font_items_group = g_slist_reverse (priv->font_items_group);
843 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
844 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
845 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
846 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
847 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
848 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
849 priv->font_face_toolitem = tool_item;
851 /* Set expand and homogeneous for remaining items */
852 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
853 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
854 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
855 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
856 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
857 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
858 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
859 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
860 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
868 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
871 ModestWindowPrivate *parent_priv;
872 ModestMsgEditWindowPrivate *priv;
873 GtkActionGroup *action_group;
874 GError *error = NULL;
875 GdkPixbuf *window_icon = NULL;
878 gboolean prefer_formatted;
880 ModestPair *account_pair = NULL;
882 g_return_val_if_fail (msg, NULL);
883 g_return_val_if_fail (account_name, NULL);
885 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
887 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
888 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
890 parent_priv->ui_manager = gtk_ui_manager_new();
891 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
892 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
894 /* Add common actions */
895 gtk_action_group_add_actions (action_group,
896 modest_msg_edit_action_entries,
897 G_N_ELEMENTS (modest_msg_edit_action_entries),
899 gtk_action_group_add_toggle_actions (action_group,
900 modest_msg_edit_toggle_action_entries,
901 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
903 gtk_action_group_add_radio_actions (action_group,
904 modest_msg_edit_alignment_radio_action_entries,
905 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
907 G_CALLBACK (modest_ui_actions_on_change_justify),
909 gtk_action_group_add_radio_actions (action_group,
910 modest_msg_edit_zoom_action_entries,
911 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
913 G_CALLBACK (modest_ui_actions_on_change_zoom),
915 gtk_action_group_add_radio_actions (action_group,
916 modest_msg_edit_priority_action_entries,
917 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
919 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
921 gtk_action_group_add_radio_actions (action_group,
922 modest_msg_edit_file_format_action_entries,
923 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
924 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
925 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
927 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
928 g_object_unref (action_group);
930 /* Load the UI definition */
931 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
934 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
935 g_clear_error (&error);
938 /* Add accelerators */
939 gtk_window_add_accel_group (GTK_WINDOW (obj),
940 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
943 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
944 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
947 init_window (MODEST_MSG_EDIT_WINDOW(obj));
949 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
951 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
953 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
955 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
957 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
958 if (account_pair != NULL)
959 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
961 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
963 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
965 /* Set window icon */
966 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
968 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
969 g_object_unref (window_icon);
972 /* Dim at start clipboard actions */
973 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
974 gtk_action_set_sensitive (action, FALSE);
975 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
976 gtk_action_set_sensitive (action, FALSE);
977 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
978 gtk_action_set_sensitive (action, FALSE);
980 /* Update select all */
981 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
982 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
983 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
984 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
985 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
987 /* set initial state of cc and bcc */
988 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
989 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
990 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
991 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
992 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
993 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
995 /* Setup the file format */
996 conf = modest_runtime_get_conf ();
997 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
999 g_clear_error (&error);
1000 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
1002 file_format = (prefer_formatted) ?
1003 MODEST_FILE_FORMAT_FORMATTED_TEXT :
1004 MODEST_FILE_FORMAT_PLAIN_TEXT;
1005 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
1007 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
1009 return (ModestWindow*) obj;
1013 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1015 GString **string_buffer = (GString **) user_data;
1017 *string_buffer = g_string_append (*string_buffer, buffer);
1023 * @result: A new string which should be freed with g_free().
1026 get_formatted_data (ModestMsgEditWindow *edit_window)
1028 ModestMsgEditWindowPrivate *priv;
1029 GString *string_buffer = g_string_new ("");
1031 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1033 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1035 return g_string_free (string_buffer, FALSE);
1040 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1043 const gchar *account_name;
1044 ModestMsgEditWindowPrivate *priv;
1046 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1048 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1050 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1051 g_return_val_if_fail (account_name, NULL);
1054 /* don't free these (except from) */
1055 data = g_slice_new0 (MsgData);
1056 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1058 data->account_name = g_strdup (account_name);
1059 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1060 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1061 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1062 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1063 if (priv->draft_msg) {
1064 data->draft_msg = g_object_ref (priv->draft_msg);
1066 data->draft_msg = NULL;
1069 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1071 gtk_text_buffer_get_bounds (buf, &b, &e);
1072 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1074 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1075 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1077 data->html_body = NULL;
1079 /* deep-copy the data */
1080 GList *cursor = priv->attachments;
1081 data->attachments = NULL;
1083 if (!(TNY_IS_MIME_PART(cursor->data))) {
1084 g_warning ("strange data in attachment list");
1085 cursor = g_list_next (cursor);
1088 data->attachments = g_list_append (data->attachments,
1089 g_object_ref (cursor->data));
1090 cursor = g_list_next (cursor);
1093 data->priority_flags = priv->priority_flags;
1100 unref_gobject (GObject *obj, gpointer data)
1102 if (!G_IS_OBJECT(obj))
1104 g_object_unref (obj);
1108 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1111 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1119 g_free (data->subject);
1120 g_free (data->plain_body);
1121 g_free (data->html_body);
1122 g_free (data->account_name);
1124 if (data->draft_msg != NULL) {
1125 g_object_unref (data->draft_msg);
1126 data->draft_msg = NULL;
1129 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1130 g_list_free (data->attachments);
1132 g_slice_free (MsgData, data);
1136 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1139 ModestMsgEditWindowPrivate *priv = NULL;
1140 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1142 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1144 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1146 return MODEST_MSG_EDIT_FORMAT_HTML;
1148 return MODEST_MSG_EDIT_FORMAT_TEXT;
1152 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1153 ModestMsgEditFormat format)
1155 ModestMsgEditWindowPrivate *priv;
1157 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1158 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1161 case MODEST_MSG_EDIT_FORMAT_HTML:
1162 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1164 case MODEST_MSG_EDIT_FORMAT_TEXT:
1165 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1168 g_return_if_reached ();
1172 ModestMsgEditFormatState *
1173 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1175 ModestMsgEditFormatState *format_state = NULL;
1176 ModestMsgEditWindowPrivate *priv;
1177 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1179 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1180 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1182 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1184 format_state = g_new0 (ModestMsgEditFormatState, 1);
1185 format_state->bold = buffer_format->bold&0x1;
1186 format_state->italics = buffer_format->italic&0x1;
1187 format_state->bullet = buffer_format->bullet&0x1;
1188 format_state->color = buffer_format->color;
1189 format_state->font_size = buffer_format->font_size;
1190 format_state->font_family = wp_get_font_name (buffer_format->font);
1191 format_state->justification = buffer_format->justification;
1192 g_free (buffer_format);
1194 return format_state;
1199 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1200 const ModestMsgEditFormatState *format_state)
1202 ModestMsgEditWindowPrivate *priv;
1203 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1204 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1205 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1206 g_return_if_fail (format_state != NULL);
1208 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1209 gtk_widget_grab_focus (priv->msg_body);
1210 buffer_format->bold = (format_state->bold != FALSE);
1211 buffer_format->italic = (format_state->italics != FALSE);
1212 buffer_format->color = format_state->color;
1213 buffer_format->font_size = format_state->font_size;
1214 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1215 buffer_format->justification = format_state->justification;
1216 buffer_format->bullet = format_state->bullet;
1218 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1220 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1221 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1222 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1223 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1224 buffer_format->cs.font = (buffer_format->font != current_format->font);
1225 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1226 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1228 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1229 if (buffer_format->cs.bold) {
1230 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1232 if (buffer_format->cs.italic) {
1233 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1235 if (buffer_format->cs.color) {
1236 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1238 if (buffer_format->cs.font_size) {
1239 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, (gpointer) (buffer_format->font_size));
1241 if (buffer_format->cs.justification) {
1242 switch (buffer_format->justification) {
1243 case GTK_JUSTIFY_LEFT:
1244 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1246 case GTK_JUSTIFY_CENTER:
1247 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1249 case GTK_JUSTIFY_RIGHT:
1250 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1257 if (buffer_format->cs.font) {
1258 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, (gpointer) (buffer_format->font));
1260 if (buffer_format->cs.bullet) {
1261 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1263 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1264 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1266 g_free (current_format);
1271 toggle_action_set_active_block_notify (GtkToggleAction *action,
1274 GSList *proxies = NULL;
1276 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1277 proxies != NULL; proxies = g_slist_next (proxies)) {
1278 GtkWidget *widget = (GtkWidget *) proxies->data;
1279 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1282 gtk_toggle_action_set_active (action, value);
1284 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1285 proxies != NULL; proxies = g_slist_next (proxies)) {
1286 GtkWidget *widget = (GtkWidget *) proxies->data;
1287 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1292 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1294 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1296 ModestWindowPrivate *parent_priv;
1297 ModestMsgEditWindowPrivate *priv;
1298 GtkWidget *new_size_menuitem;
1299 GtkWidget *new_font_menuitem;
1301 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1302 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1304 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1305 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1306 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1307 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1309 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1310 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1311 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1314 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1316 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1317 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1319 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1320 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1322 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1323 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1325 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1326 G_CALLBACK (modest_msg_edit_window_color_button_change),
1328 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1329 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1330 G_CALLBACK (modest_msg_edit_window_color_button_change),
1333 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1334 buffer_format->font_size))->data);
1335 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1339 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1340 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1341 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1343 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1344 G_CALLBACK (modest_msg_edit_window_size_change),
1346 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1347 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1348 G_CALLBACK (modest_msg_edit_window_size_change),
1352 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1353 buffer_format->font))->data);
1354 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1358 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1359 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1360 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1362 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1363 G_CALLBACK (modest_msg_edit_window_font_change),
1365 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1366 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1367 G_CALLBACK (modest_msg_edit_window_font_change),
1371 g_free (buffer_format);
1377 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1380 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1381 ModestMsgEditWindowPrivate *priv;
1382 GtkWidget *dialog = NULL;
1384 const GdkColor *new_color = NULL;
1386 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1387 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1389 #ifdef MODEST_HILDON_VERSION_0
1390 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1391 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1393 dialog = hildon_color_chooser_new ();
1394 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1395 #endif /*MODEST_HILDON_VERSION_0*/
1396 g_free (buffer_format);
1398 response = gtk_dialog_run (GTK_DIALOG (dialog));
1400 case GTK_RESPONSE_OK: {
1401 #ifdef MODEST_HILDON_VERSION_0
1402 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1405 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1407 #endif /*MODEST_HILDON_VERSION_0*/
1414 gtk_widget_destroy (dialog);
1416 if (new_color != NULL)
1417 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1422 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1425 ModestMsgEditWindowPrivate *priv;
1426 GtkWidget *dialog = NULL;
1428 GdkColor *old_color = NULL;
1429 const GdkColor *new_color = NULL;
1431 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1432 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1434 #ifdef MODEST_HILDON_VERSION_0
1435 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1436 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1438 dialog = hildon_color_chooser_new ();
1439 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1440 #endif /*MODEST_HILDON_VERSION_9*/
1442 response = gtk_dialog_run (GTK_DIALOG (dialog));
1444 case GTK_RESPONSE_OK: {
1445 #ifdef MODEST_HILDON_VERSION_0
1446 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1449 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1451 #endif /*MODEST_HILDON_VERSION_0*/
1457 gtk_widget_destroy (dialog);
1459 if (new_color != NULL)
1460 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1466 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1469 ModestMsgEditWindowPrivate *priv;
1470 GtkWidget *dialog = NULL;
1472 GSList *uris = NULL;
1473 GSList *uri_node = NULL;
1475 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1477 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1478 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1479 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1481 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1483 response = gtk_dialog_run (GTK_DIALOG (dialog));
1485 case GTK_RESPONSE_OK:
1486 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1491 gtk_widget_destroy (dialog);
1493 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1495 GnomeVFSHandle *handle = NULL;
1496 GnomeVFSResult result;
1497 GtkTextIter position;
1498 GtkTextMark *insert_mark;
1500 uri = (const gchar *) uri_node->data;
1501 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1502 if (result == GNOME_VFS_OK) {
1503 GdkPixbufLoader *loader;
1505 GnomeVFSFileInfo info;
1506 gchar *filename, *basename, *escaped_filename;
1507 TnyMimePart *mime_part;
1510 const gchar *mime_type = NULL;
1511 GnomeVFSURI *vfs_uri;
1513 vfs_uri = gnome_vfs_uri_new (uri);
1515 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
1516 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
1517 g_free (escaped_filename);
1518 gnome_vfs_uri_unref (vfs_uri);
1520 if (gnome_vfs_get_file_info (uri, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
1521 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
1523 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1525 mime_part = tny_platform_factory_new_mime_part
1526 (modest_runtime_get_platform_factory ());
1527 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1529 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1531 content_id = g_strdup_printf ("%d", priv->last_cid);
1532 tny_mime_part_set_content_id (mime_part, content_id);
1533 g_free (content_id);
1536 basename = g_path_get_basename (filename);
1537 tny_mime_part_set_filename (mime_part, basename);
1540 tny_stream_reset (TNY_STREAM (stream));
1541 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1542 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1543 unsigned char read_buffer[128];
1545 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1546 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1549 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1550 g_object_ref (pixbuf);
1551 gdk_pixbuf_loader_close (loader, NULL);
1552 g_object_unref (loader);
1554 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1555 GdkPixbuf *new_pixbuf;
1557 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1558 gdk_pixbuf_get_width (pixbuf);
1559 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1560 g_object_unref (pixbuf);
1561 pixbuf = new_pixbuf;
1564 if (pixbuf != NULL) {
1565 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1566 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1567 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1570 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1571 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1573 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1574 gtk_widget_show_all (priv->attachments_caption);
1575 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1585 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1588 ModestMsgEditWindowPrivate *priv;
1589 GtkWidget *dialog = NULL;
1591 GSList *uris = NULL;
1594 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1596 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1597 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
1598 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1600 response = gtk_dialog_run (GTK_DIALOG (dialog));
1602 case GTK_RESPONSE_OK:
1603 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1608 gtk_widget_destroy (dialog);
1610 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1612 GnomeVFSHandle *handle = NULL;
1613 GnomeVFSResult result;
1615 uri = (const gchar *) uri_node->data;
1616 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1617 if (result == GNOME_VFS_OK) {
1618 TnyMimePart *mime_part;
1620 const gchar *mime_type = NULL;
1622 gchar *escaped_filename;
1625 GnomeVFSFileInfo info;
1626 GnomeVFSURI *vfs_uri;
1628 vfs_uri = gnome_vfs_uri_new (uri);
1631 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
1632 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
1633 g_free (escaped_filename);
1634 gnome_vfs_uri_unref (vfs_uri);
1636 if (gnome_vfs_get_file_info (uri,
1638 GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
1639 GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
1641 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1642 mime_part = tny_platform_factory_new_mime_part
1643 (modest_runtime_get_platform_factory ());
1644 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1646 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1648 content_id = g_strdup_printf ("%d", priv->last_cid);
1649 tny_mime_part_set_content_id (mime_part, content_id);
1650 g_free (content_id);
1653 basename = g_path_get_basename (filename);
1654 tny_mime_part_set_filename (mime_part, basename);
1657 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1658 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1660 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1661 gtk_widget_show_all (priv->attachments_caption);
1662 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1667 g_slist_foreach (uris, (GFunc) g_free, NULL);
1668 g_slist_free (uris);
1672 modest_msg_edit_window_attach_file_noninteractive (
1673 ModestMsgEditWindow *window,
1674 const gchar *file_uri)
1677 ModestMsgEditWindowPrivate *priv;
1679 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1681 if (file_uri && strlen(file_uri)) {
1684 /* TODO: We should probably try to use only the URI,
1685 * instead of using a filename.
1687 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1689 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1692 file_id = g_open (filename, O_RDONLY, 0);
1693 if (file_id != -1) {
1694 TnyMimePart *mime_part;
1696 const gchar *mime_type;
1699 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1700 mime_type = gnome_vfs_get_mime_type(filename);
1702 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1704 mime_part = tny_platform_factory_new_mime_part
1705 (modest_runtime_get_platform_factory ());
1706 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1708 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1710 content_id = g_strdup_printf ("%d", priv->last_cid);
1711 tny_mime_part_set_content_id (mime_part, content_id);
1712 g_free (content_id);
1715 basename = g_path_get_basename (filename);
1716 tny_mime_part_set_filename (mime_part, basename);
1719 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1720 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1722 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1723 gtk_widget_show_all (priv->attachments_caption);
1724 } else if (file_id == -1) {
1726 g_warning("file to be attached does not exist: %s", filename);
1734 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1737 ModestMsgEditWindowPrivate *priv;
1738 gboolean clean_list = FALSE;
1740 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1741 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1743 if (att_list == NULL) {
1744 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1748 if (att_list == NULL) {
1749 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1751 GtkWidget *confirmation_dialog = NULL;
1752 gboolean dialog_response;
1754 gchar *message = NULL;
1755 const gchar *filename = NULL;
1757 if (att_list->next == NULL) {
1758 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1762 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1763 att_list->next == NULL), filename);
1764 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1766 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1767 gtk_widget_destroy (confirmation_dialog);
1768 if (!dialog_response) {
1770 g_list_free (att_list);
1773 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1775 for (node = att_list; node != NULL; node = g_list_next (node)) {
1776 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1777 const gchar *att_id;
1778 priv->attachments = g_list_remove (priv->attachments, mime_part);
1780 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1782 if (priv->attachments == NULL)
1783 gtk_widget_hide (priv->attachments_caption);
1784 att_id = tny_mime_part_get_content_id (mime_part);
1786 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1788 g_object_unref (mime_part);
1789 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1794 g_list_free (att_list);
1798 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1801 ModestMsgEditWindowPrivate *priv;
1802 GdkColor *new_color;
1803 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1805 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1806 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1809 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1811 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1813 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1815 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1820 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1823 ModestMsgEditWindowPrivate *priv;
1824 gint new_size_index;
1825 ModestMsgEditWindow *window;
1828 window = MODEST_MSG_EDIT_WINDOW (userdata);
1829 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1830 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1832 if (gtk_check_menu_item_get_active (menu_item)) {
1834 WPTextBufferFormat format;
1836 memset (&format, 0, sizeof (format));
1837 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
1839 label = gtk_bin_get_child (GTK_BIN (menu_item));
1841 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1842 format.cs.font_size = TRUE;
1843 format.cs.text_position = TRUE;
1844 format.cs.font = TRUE;
1845 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1846 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
1848 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1849 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1850 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1852 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1853 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1854 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1860 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1863 ModestMsgEditWindowPrivate *priv;
1864 gint new_font_index;
1865 ModestMsgEditWindow *window;
1868 window = MODEST_MSG_EDIT_WINDOW (userdata);
1869 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1870 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1872 if (gtk_check_menu_item_get_active (menu_item)) {
1875 label = gtk_bin_get_child (GTK_BIN (menu_item));
1877 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1879 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1880 (gpointer) new_font_index))
1881 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1883 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1884 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1885 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1891 modest_msg_edit_window_set_zoom (ModestWindow *window,
1894 ModestMsgEditWindowPrivate *priv;
1895 ModestWindowPrivate *parent_priv;
1896 GtkRadioAction *zoom_radio_action;
1898 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1900 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1901 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1902 priv->zoom_level = zoom;
1903 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom*DEFAULT_FONT_SCALE);
1905 /* Zoom level menu options should be updated with the current zoom level */
1906 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1907 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1908 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1909 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1910 /* FIXME: Not availible before Gtk 2.10 */
1912 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1917 modest_msg_edit_window_get_zoom (ModestWindow *window)
1919 ModestMsgEditWindowPrivate *priv;
1921 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1923 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1924 return priv->zoom_level;
1928 zoom_allowed (ModestMsgEditWindow *window)
1932 focus = gtk_window_get_focus (GTK_WINDOW (window));
1933 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1937 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1939 ModestWindowPrivate *parent_priv;
1940 GtkRadioAction *zoom_radio_action;
1941 GSList *group, *node;
1943 /* First we check if the text view is focused. If not, zooming is not allowed */
1944 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1945 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1949 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1950 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1951 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1953 group = gtk_radio_action_get_group (zoom_radio_action);
1955 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1956 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1960 for (node = group; node != NULL; node = g_slist_next (node)) {
1961 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1962 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1970 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1972 ModestWindowPrivate *parent_priv;
1973 GtkRadioAction *zoom_radio_action;
1974 GSList *group, *node;
1976 /* First we check if the text view is focused. If not, zooming is not allowed */
1977 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1978 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1982 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1983 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1984 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1986 group = gtk_radio_action_get_group (zoom_radio_action);
1988 for (node = group; node != NULL; node = g_slist_next (node)) {
1989 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1990 if (node->next != NULL) {
1991 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1994 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
2002 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
2004 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
2005 ModestWindowPrivate *parent_priv;
2006 ModestWindowMgr *mgr;
2007 gboolean is_fullscreen;
2008 GtkAction *fs_toggle_action;
2011 mgr = modest_runtime_get_window_mgr ();
2012 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
2014 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
2016 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2017 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2018 if (is_fullscreen != active)
2019 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2027 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
2029 ModestWindowPrivate *parent_priv;
2030 GtkAction *fs_toggle_action;
2033 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2035 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2036 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
2037 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
2041 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2044 ModestMsgEditWindowPrivate *priv = NULL;
2045 const gchar *recipients;
2046 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2048 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2049 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2050 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
2051 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2052 gtk_widget_show (priv->cc_caption);
2054 gtk_widget_hide (priv->cc_caption);
2055 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2059 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2062 ModestMsgEditWindowPrivate *priv = NULL;
2063 const gchar *recipients;
2064 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2066 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2067 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2068 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2069 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2070 gtk_widget_show (priv->bcc_caption);
2072 gtk_widget_hide (priv->bcc_caption);
2073 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2077 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2078 ModestRecptEditor *editor)
2080 ModestMsgEditWindowPrivate *priv;
2082 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2083 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2084 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2086 if (editor == NULL) {
2087 GtkWidget *view_focus;
2088 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2090 /* This code should be kept in sync with ModestRecptEditor. The
2091 textview inside the recpt editor is the one that really gets the
2092 focus. As it's inside a scrolled window, and this one inside the
2093 hbox recpt editor inherits from, we'll need to go up in the
2094 hierarchy to know if the text view is part of the recpt editor
2095 or if it's a different text entry */
2097 if (gtk_widget_get_parent (view_focus)) {
2098 GtkWidget *first_parent;
2100 first_parent = gtk_widget_get_parent (view_focus);
2101 if (gtk_widget_get_parent (first_parent) &&
2102 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2103 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2108 editor = MODEST_RECPT_EDITOR (priv->to_field);
2112 modest_address_book_select_addresses (editor);
2117 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2119 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2121 modest_msg_edit_window_open_addressbook (window, NULL);
2125 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2126 gboolean show_toolbar)
2128 ModestWindowPrivate *parent_priv;
2130 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2131 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2133 /* FIXME: we can not just use the code of
2134 modest_msg_edit_window_setup_toolbar because it has a
2135 mixture of both initialization and creation code. */
2138 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2140 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2144 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2145 TnyHeaderFlags priority_flags)
2147 ModestMsgEditWindowPrivate *priv;
2148 ModestWindowPrivate *parent_priv;
2150 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2152 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2153 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2154 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2156 if (priv->priority_flags != priority_flags) {
2157 GtkAction *priority_action = NULL;
2159 priv->priority_flags = priority_flags;
2161 switch (priority_flags) {
2162 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2163 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2164 gtk_widget_show (priv->priority_icon);
2165 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2166 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2168 case TNY_HEADER_FLAG_LOW_PRIORITY:
2169 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2170 gtk_widget_show (priv->priority_icon);
2171 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2172 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2175 gtk_widget_hide (priv->priority_icon);
2176 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2177 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2180 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2181 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2186 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2189 ModestMsgEditWindowPrivate *priv;
2190 ModestWindowPrivate *parent_priv;
2191 gint current_format;
2193 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2195 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2196 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2198 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2199 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2201 if (current_format != file_format) {
2202 switch (file_format) {
2203 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2204 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2206 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2210 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2211 response = gtk_dialog_run (GTK_DIALOG (dialog));
2212 gtk_widget_destroy (dialog);
2213 if (response == GTK_RESPONSE_OK) {
2214 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2216 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2217 toggle_action_set_active_block_notify (action, TRUE);
2222 update_dimmed (window);
2227 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2230 ModestMsgEditWindowPrivate *priv;
2231 WPTextBufferFormat oldfmt, fmt;
2232 gint old_position = 0;
2236 GdkColor *color = NULL;
2237 gboolean bold, bold_set, italic, italic_set;
2238 gboolean underline, underline_set;
2239 gboolean strikethrough, strikethrough_set;
2240 gboolean position_set;
2241 gboolean font_size_set, font_set, color_set;
2244 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2245 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2247 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2249 /* First we get the currently selected font information */
2250 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2251 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2253 switch (oldfmt.text_position) {
2254 case TEXT_POSITION_NORMAL:
2257 case TEXT_POSITION_SUPERSCRIPT:
2265 g_object_set (G_OBJECT (dialog),
2266 "bold", oldfmt.bold != FALSE,
2267 "bold-set", !oldfmt.cs.bold,
2268 "underline", oldfmt.underline != FALSE,
2269 "underline-set", !oldfmt.cs.underline,
2270 "italic", oldfmt.italic != FALSE,
2271 "italic-set", !oldfmt.cs.italic,
2272 "strikethrough", oldfmt.strikethrough != FALSE,
2273 "strikethrough-set", !oldfmt.cs.strikethrough,
2274 "color", &oldfmt.color,
2275 "color-set", !oldfmt.cs.color,
2276 "size", wp_font_size[oldfmt.font_size],
2277 "size-set", !oldfmt.cs.font_size,
2278 "position", old_position,
2279 "position-set", !oldfmt.cs.text_position,
2280 "family", wp_get_font_name (oldfmt.font),
2281 "family-set", !oldfmt.cs.font,
2284 gtk_widget_show_all (dialog);
2285 response = gtk_dialog_run (GTK_DIALOG (dialog));
2286 if (response == GTK_RESPONSE_OK) {
2288 g_object_get( dialog,
2290 "bold-set", &bold_set,
2291 "underline", &underline,
2292 "underline-set", &underline_set,
2294 "italic-set", &italic_set,
2295 "strikethrough", &strikethrough,
2296 "strikethrough-set", &strikethrough_set,
2298 "color-set", &color_set,
2300 "size-set", &font_size_set,
2301 "family", &font_name,
2302 "family-set", &font_set,
2303 "position", &position,
2304 "position-set", &position_set,
2309 if (response == GTK_RESPONSE_OK) {
2310 memset(&fmt, 0, sizeof(fmt));
2316 fmt.italic = italic;
2317 fmt.cs.italic = TRUE;
2319 if (underline_set) {
2320 fmt.underline = underline;
2321 fmt.cs.underline = TRUE;
2323 if (strikethrough_set) {
2324 fmt.strikethrough = strikethrough;
2325 fmt.cs.strikethrough = TRUE;
2330 ? TEXT_POSITION_NORMAL
2331 : ( ( position == 1 )
2332 ? TEXT_POSITION_SUPERSCRIPT
2333 : TEXT_POSITION_SUBSCRIPT );
2334 fmt.cs.text_position = TRUE;
2338 fmt.cs.color = TRUE;
2341 fmt.font = wp_get_font_index(font_name,
2346 if (font_size_set) {
2347 fmt.font_size = wp_get_font_size_index(
2348 font_size, DEFAULT_FONT_SIZE);
2349 fmt.cs.font_size = TRUE;
2351 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2353 gtk_widget_destroy (dialog);
2355 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2359 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2361 ModestMsgEditWindowPrivate *priv;
2363 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2364 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2366 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2368 update_dimmed (window);
2373 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2375 ModestMsgEditWindowPrivate *priv;
2377 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2378 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2380 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2382 update_dimmed (window);
2387 update_dimmed (ModestMsgEditWindow *window)
2389 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2390 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2394 gboolean editor_focused;
2396 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2397 editor_focused = gtk_widget_is_focus (priv->msg_body);
2399 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2400 gtk_action_set_sensitive (action, rich_text && editor_focused);
2401 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2402 gtk_action_set_sensitive (action, rich_text && editor_focused);
2403 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2404 gtk_action_set_sensitive (action, rich_text && editor_focused);
2405 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2406 gtk_action_set_sensitive (action, rich_text && editor_focused);
2407 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2408 gtk_action_set_sensitive (action, rich_text && editor_focused);
2409 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2410 gtk_action_set_sensitive (action, rich_text && editor_focused);
2411 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2412 gtk_action_set_sensitive (action, rich_text && editor_focused);
2413 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2414 gtk_action_set_sensitive (action, rich_text && editor_focused);
2415 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2416 gtk_action_set_sensitive (action, rich_text && editor_focused);
2417 widget = priv->font_color_button;
2418 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2419 widget = priv->font_size_toolitem;
2420 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2421 widget = priv->font_face_toolitem;
2422 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2426 setup_insensitive_handlers (ModestMsgEditWindow *window)
2428 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2429 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2432 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2433 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2434 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2435 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2436 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2437 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2438 widget = priv->font_color_button;
2439 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2440 widget = priv->font_size_toolitem;
2441 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2442 widget = priv->font_face_toolitem;
2443 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2448 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2450 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2453 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2454 gtk_action_set_sensitive (action, can_undo);
2458 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2460 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2463 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu");
2464 gtk_action_set_sensitive (action, can_redo);
2468 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2471 GtkTextIter match_start, match_end;
2473 if (image_id == NULL)
2476 gtk_text_buffer_get_start_iter (buffer, &iter);
2478 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2479 GSList *tags = gtk_text_iter_get_tags (&match_start);
2481 for (node = tags; node != NULL; node = g_slist_next (node)) {
2482 GtkTextTag *tag = (GtkTextTag *) node->data;
2483 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2484 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2485 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2487 offset = gtk_text_iter_get_offset (&match_start);
2488 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2489 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2493 gtk_text_iter_forward_char (&iter);
2498 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2500 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2501 GtkTextIter real_start, real_end;
2502 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2504 if (gtk_text_iter_compare (start, end) > 0) {
2508 real_start = *start;
2512 GSList *tags = gtk_text_iter_get_tags (&real_start);
2514 for (node = tags; node != NULL; node = g_slist_next (node)) {
2515 GtkTextTag *tag = (GtkTextTag *) node->data;
2516 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2517 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2519 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2521 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2524 } while (gtk_text_iter_forward_char (&real_start)&&
2525 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2529 msg_body_focus (GtkWidget *focus,
2530 GdkEventFocus *event,
2534 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2539 recpt_field_changed (GtkTextBuffer *buffer,
2540 ModestMsgEditWindow *editor)
2542 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2543 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2544 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2545 gboolean dim = FALSE;
2548 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2549 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2550 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2552 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2553 gtk_text_buffer_get_char_count (cc_buffer) +
2554 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2556 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2557 gtk_action_set_sensitive (action, !dim);
2558 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2559 gtk_action_set_sensitive (action, !dim);
2563 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2565 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2569 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2571 gboolean rich_text, editor_focused;
2573 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2574 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2575 editor_focused = gtk_widget_is_focus (priv->msg_body);
2578 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2579 else if (!editor_focused)
2580 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2584 reset_modified (ModestMsgEditWindow *editor)
2586 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2587 GtkTextBuffer *buffer;
2589 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2590 gtk_text_buffer_set_modified (buffer, FALSE);
2591 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2592 gtk_text_buffer_set_modified (buffer, FALSE);
2593 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2594 gtk_text_buffer_set_modified (buffer, FALSE);
2595 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2599 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2601 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2602 GtkTextBuffer *buffer;
2604 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2605 if (gtk_text_buffer_get_modified (buffer))
2607 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2608 if (gtk_text_buffer_get_modified (buffer))
2610 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2611 if (gtk_text_buffer_get_modified (buffer))
2613 if (gtk_text_buffer_get_modified (priv->text_buffer))
2620 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2622 ModestMsgEditWindowPrivate *priv = NULL;
2624 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2625 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2627 /* check if there's no recipient added */
2628 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2629 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2630 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2631 /* no recipient contents, then select contacts */
2632 modest_msg_edit_window_open_addressbook (window, NULL);
2636 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2638 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2640 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2643 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2650 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2651 ModestMsgEditWindow *window)
2653 modest_msg_edit_window_attach_file (window);
2657 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2659 ModestMsgEditWindow *window)
2661 ModestWindowPrivate *parent_priv;
2662 ModestMsgEditWindowPrivate *priv;
2664 gboolean has_selection;
2666 GList *selected_attachments = NULL;
2667 gint n_att_selected = 0;
2669 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2670 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2672 if (!GTK_WIDGET_VISIBLE (window))
2674 has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL);
2675 focused = gtk_window_get_focus (GTK_WINDOW (window));
2677 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2678 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2679 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2680 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2682 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2683 n_att_selected = g_list_length (selected_attachments);
2684 g_list_free (selected_attachments);
2686 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2687 gtk_action_set_sensitive (action, n_att_selected == 1);
2689 update_paste_dimming (window);
2693 update_window_title (ModestMsgEditWindow *window)
2695 ModestMsgEditWindowPrivate *priv = NULL;
2696 const gchar *subject;
2698 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2699 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2700 if (subject == NULL || subject[0] == '\0')
2701 subject = _("mail_va_new_email");
2703 gtk_window_set_title (GTK_WINDOW (window), subject);
2708 subject_field_changed (GtkEditable *editable,
2709 ModestMsgEditWindow *window)
2711 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2712 update_window_title (window);
2713 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2717 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2720 ModestMsgEditWindowPrivate *priv = NULL;
2722 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2723 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2725 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2727 gtk_widget_show_all (priv->find_toolbar);
2728 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2730 gtk_widget_hide_all (priv->find_toolbar);
2731 gtk_widget_grab_focus (priv->msg_body);
2737 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2739 GtkTextIter *match_start,
2740 GtkTextIter *match_end)
2742 GtkTextIter end_iter;
2743 gchar *str_casefold;
2746 gchar *range_casefold;
2749 gboolean result = FALSE;
2756 gtk_text_iter_forward_to_end (&end_iter);
2758 str_casefold = g_utf8_casefold (str, -1);
2759 str_chars_n = strlen (str);
2761 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2762 range_casefold = g_utf8_casefold (range_text, -1);
2763 range_chars_n = strlen (range_casefold);
2765 if (range_chars_n < str_chars_n) {
2766 g_free (str_casefold);
2767 g_free (range_text);
2768 g_free (range_casefold);
2772 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2773 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2774 if (!g_utf8_collate (range_subtext, str_casefold)) {
2775 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2777 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2778 match_start, match_end, NULL);
2779 g_free (found_text);
2781 g_free (range_subtext);
2785 g_free (str_casefold);
2786 g_free (range_text);
2787 g_free (range_casefold);
2794 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2795 ModestMsgEditWindow *window)
2797 gchar *current_search = NULL;
2798 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2800 GtkTextIter selection_start, selection_end;
2801 GtkTextIter match_start, match_end;
2802 gboolean continue_search = FALSE;
2804 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2805 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2806 g_free (current_search);
2807 g_free (priv->last_search);
2808 priv->last_search = NULL;
2809 /* Information banner about empty search */
2810 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2814 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2815 continue_search = TRUE;
2817 g_free (priv->last_search);
2818 priv->last_search = g_strdup (current_search);
2821 if (continue_search) {
2822 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2823 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2824 &match_start, &match_end);
2826 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2828 GtkTextIter buffer_start;
2829 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2830 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2831 &match_start, &match_end);
2833 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2836 /* Mark as selected the string found in search */
2838 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2839 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2841 g_free (priv->last_search);
2842 priv->last_search = NULL;
2844 g_free (current_search);
2848 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2849 ModestMsgEditWindow *window)
2851 GtkToggleAction *toggle;
2852 ModestWindowPrivate *parent_priv;
2853 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2855 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2856 gtk_toggle_action_set_active (toggle, FALSE);
2861 update_paste_dimming (ModestMsgEditWindow *window)
2863 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2864 GtkAction *action = NULL;
2865 GtkClipboard *clipboard = NULL;
2869 focused = gtk_window_get_focus (GTK_WINDOW (window));
2871 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2872 active = gtk_clipboard_wait_is_text_available (clipboard);
2875 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2879 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2880 gtk_action_set_sensitive (action, active);
2885 update_select_all_dimming (ModestMsgEditWindow *window)
2888 gboolean dimmed = FALSE;
2890 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2892 focused = gtk_window_get_focus (GTK_WINDOW (window));
2893 if (GTK_IS_ENTRY (focused)) {
2894 const gchar *current_text;
2895 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2896 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2897 } else if (GTK_IS_TEXT_VIEW (focused)) {
2898 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2899 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2900 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2903 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2904 gtk_action_set_sensitive (action, !dimmed);
2908 update_zoom_dimming (ModestMsgEditWindow *window)
2911 gboolean dimmed = FALSE;
2913 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2915 focused = gtk_window_get_focus (GTK_WINDOW (window));
2916 dimmed = ! WP_IS_TEXT_VIEW (focused);
2917 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2918 gtk_action_set_sensitive (action, !dimmed);
2922 edit_menu_activated (GtkAction *action,
2925 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2927 update_select_all_dimming (window);
2928 update_paste_dimming (window);
2931 view_menu_activated (GtkAction *action,
2934 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2936 update_zoom_dimming (window);
2940 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2942 ModestMsgEditWindowPrivate *priv;
2944 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2949 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
2952 ModestMsgEditWindowPrivate *priv;
2954 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2960 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
2963 ModestMsgEditWindowPrivate *priv;
2964 TnyHeader *header = NULL;
2966 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2967 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
2969 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2970 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
2972 if (priv->draft_msg != NULL) {
2973 header = tny_msg_get_header (priv->draft_msg);
2974 if (TNY_IS_HEADER (header)) {
2975 modest_window_mgr_unregister_header (mgr, header);
2977 g_object_unref (priv->draft_msg);
2980 if (draft != NULL) {
2981 g_object_ref (draft);
2982 header = tny_msg_get_header (draft);
2983 if (TNY_IS_HEADER (header))
2984 modest_window_mgr_register_header (mgr, header);
2987 priv->draft_msg = draft;