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 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
388 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
389 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
390 priv->add_attachment_button = gtk_button_new ();
391 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
392 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
393 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
394 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
395 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
396 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
397 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
398 priv->attachments_view = modest_attachments_view_new (NULL);
400 priv->header_box = gtk_vbox_new (FALSE, 0);
402 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
403 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
404 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
405 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
406 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
407 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
408 g_object_unref (size_group);
410 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
411 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
412 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
413 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
414 gtk_size_group_add_widget (size_group, priv->subject_field);
415 gtk_size_group_add_widget (size_group, priv->attachments_view);
416 g_object_unref (size_group);
418 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
419 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
420 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
421 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
422 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
423 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
424 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
427 priv->msg_body = wp_text_view_new ();
428 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
429 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
430 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
431 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
432 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
433 gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
435 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
437 priv->find_toolbar = hildon_find_toolbar_new (NULL);
438 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
440 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
442 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
443 G_CALLBACK (text_buffer_refresh_attributes), obj);
444 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
445 G_CALLBACK (text_buffer_delete_range), obj);
446 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
447 G_CALLBACK (text_buffer_can_undo), obj);
448 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
449 G_CALLBACK (text_buffer_can_redo), obj);
450 g_signal_connect (G_OBJECT (obj), "window-state-event",
451 G_CALLBACK (modest_msg_edit_window_window_state_event),
453 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
454 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
455 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
456 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
457 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
458 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
460 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
461 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
463 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
464 G_CALLBACK (msg_body_focus), obj);
465 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
466 G_CALLBACK (msg_body_focus), obj);
467 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
468 "changed", G_CALLBACK (recpt_field_changed), obj);
469 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
470 "changed", G_CALLBACK (recpt_field_changed), obj);
471 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
472 "changed", G_CALLBACK (recpt_field_changed), obj);
473 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
474 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
476 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
477 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
479 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
480 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
481 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
483 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
485 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
486 frame = gtk_frame_new (NULL);
487 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
489 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
490 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
491 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
493 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
494 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
495 gtk_widget_hide (priv->cc_caption);
497 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
498 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
499 gtk_widget_hide (priv->bcc_caption);
502 window_box = gtk_vbox_new (FALSE, 0);
503 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
504 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
505 gtk_container_add (GTK_CONTAINER(obj), window_box);
506 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
507 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
510 TODO: scroll_area was never instantiated.
511 Stop building without warnings-as-errors. murrayc.
512 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
513 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
516 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
517 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
523 modest_msg_edit_window_finalize (GObject *obj)
525 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
527 if (priv->clipboard_change_handler_id > 0) {
528 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
529 priv->clipboard_change_handler_id = 0;
532 if (priv->draft_msg != NULL) {
533 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
534 if (TNY_IS_HEADER (header)) {
535 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
536 modest_window_mgr_unregister_header (mgr, header);
538 g_object_unref (priv->draft_msg);
539 priv->draft_msg = NULL;
542 /* This had to stay alive for as long as the combobox that used it: */
543 modest_pair_list_free (priv->from_field_protos);
545 G_OBJECT_CLASS(parent_class)->finalize (obj);
549 menubar_to_menu (GtkUIManager *ui_manager)
551 GtkWidget *main_menu;
555 /* Create new main menu */
556 main_menu = gtk_menu_new();
558 /* Get the menubar from the UI manager */
559 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
561 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
565 menu = GTK_WIDGET (iter->data);
566 gtk_widget_reparent(menu, main_menu);
568 iter = g_list_next (iter);
575 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
578 const gchar *to, *cc, *bcc, *subject;
580 ModestMsgEditWindowPrivate *priv;
582 TnyHeaderFlags priority_flags;
583 TnyFolder *msg_folder;
585 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
586 g_return_if_fail (TNY_IS_MSG (msg));
588 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
590 header = tny_msg_get_header (msg);
591 to = tny_header_get_to (header);
592 cc = tny_header_get_cc (header);
593 bcc = tny_header_get_bcc (header);
594 subject = tny_header_get_subject (header);
595 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
598 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
600 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
601 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
602 gtk_widget_show (priv->cc_caption);
603 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
604 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
605 gtk_widget_hide (priv->cc_caption);
608 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
609 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
610 gtk_widget_show (priv->bcc_caption);
611 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
612 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
613 gtk_widget_hide (priv->bcc_caption);
616 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
617 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
620 update_window_title (self);
622 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
623 body = modest_tny_msg_get_body (msg, TRUE);
625 if ((body == NULL)||(body[0] == '\0')) {
627 body = modest_text_utils_convert_to_html ("");
629 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
630 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
633 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
636 /* Get the default format required from configuration */
637 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
638 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
641 /* Set the default focus depending on having already a To: field or not */
642 if ((!to)||(*to == '\0')) {
643 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
645 gtk_widget_grab_focus (priv->msg_body);
648 /* TODO: lower priority, select in the From: combo to the
649 value that comes from msg <- not sure, should it be
652 /* Add attachments to the view */
653 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
654 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
655 if (priv->attachments == NULL) {
656 gtk_widget_hide (priv->attachments_caption);
658 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
659 gtk_widget_show_all (priv->attachments_caption);
662 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
663 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
665 reset_modified (self);
667 update_dimmed (self);
668 text_buffer_can_undo (priv->text_buffer, FALSE, self);
669 text_buffer_can_redo (priv->text_buffer, FALSE, self);
671 /* we should set a reference to the incoming message if it is a draft */
672 msg_folder = tny_msg_get_folder (msg);
674 if (modest_tny_folder_is_local_folder (msg_folder) &&
675 modest_tny_folder_get_local_folder_type (msg_folder) == TNY_FOLDER_TYPE_DRAFTS)
676 priv->draft_msg = g_object_ref(msg);
677 g_object_unref (msg_folder);
682 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
685 GList *item_children, *node;
686 GtkWidget *bin_child;
688 bin_child = gtk_bin_get_child (GTK_BIN(item));
690 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
692 for (node = item_children; node != NULL; node = g_list_next (node)) {
693 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
694 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
697 g_list_free (item_children);
701 menu_tool_button_dont_expand (GtkMenuToolButton *item)
704 GList *item_children, *node;
706 box = gtk_bin_get_child (GTK_BIN (item));
707 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
708 item_children = gtk_container_get_children (GTK_CONTAINER (box));
710 for (node = item_children; node != NULL; node = g_list_next (node)) {
711 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
712 if (GTK_IS_TOGGLE_BUTTON (node->data))
713 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
714 else if (GTK_IS_BUTTON (node->data))
715 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
717 g_list_free (item_children);
722 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
724 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
725 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
726 GtkWidget *placeholder;
727 GtkWidget *tool_item;
732 GtkWidget *sizes_menu;
733 GtkWidget *fonts_menu;
734 GSList *radio_group = NULL;
739 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
740 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
742 /* should we hide the toolbar? */
743 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
744 gtk_widget_hide (parent_priv->toolbar);
746 /* Font color placeholder */
747 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
748 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
751 tool_item = GTK_WIDGET (gtk_tool_item_new ());
752 priv->font_color_button = hildon_color_button_new ();
753 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
754 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
755 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
756 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
757 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
758 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
759 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
761 /* Font size and face placeholder */
762 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
763 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
765 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
766 priv->size_tool_button_label = gtk_label_new (NULL);
767 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
768 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
769 size_text,"</span>", NULL);
770 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
772 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
773 sizes_menu = gtk_menu_new ();
774 priv->size_items_group = NULL;
776 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
777 GtkWidget *size_menu_item;
779 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
780 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
781 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
782 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
783 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
784 gtk_widget_show (size_menu_item);
786 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
790 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
791 GtkWidget *item = (GtkWidget *) node->data;
792 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
796 priv->size_items_group = g_slist_reverse (priv->size_items_group);
797 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
798 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
799 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
800 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
801 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
802 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
803 priv->font_size_toolitem = tool_item;
806 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
807 priv->font_tool_button_label = gtk_label_new (NULL);
808 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
809 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
811 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
812 fonts_menu = gtk_menu_new ();
813 priv->font_items_group = NULL;
815 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
816 GtkWidget *font_menu_item;
817 GtkWidget *child_label;
819 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
820 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
821 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
822 wp_get_font_name (font_index), "</span>", NULL);
823 gtk_label_set_markup (GTK_LABEL (child_label), markup);
826 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
827 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
828 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
829 gtk_widget_show (font_menu_item);
831 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
834 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
835 GtkWidget *item = (GtkWidget *) node->data;
836 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
839 priv->font_items_group = g_slist_reverse (priv->font_items_group);
840 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
841 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
842 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
843 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
844 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
845 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
846 priv->font_face_toolitem = tool_item;
848 /* Set expand and homogeneous for remaining items */
849 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
850 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
851 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
852 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
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/ActionsItalics");
856 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
857 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
865 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
868 ModestWindowPrivate *parent_priv;
869 ModestMsgEditWindowPrivate *priv;
870 GtkActionGroup *action_group;
871 GError *error = NULL;
872 GdkPixbuf *window_icon = NULL;
875 gboolean prefer_formatted;
877 ModestPair *account_pair = NULL;
879 g_return_val_if_fail (msg, NULL);
880 g_return_val_if_fail (account_name, NULL);
882 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
884 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
885 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
887 parent_priv->ui_manager = gtk_ui_manager_new();
888 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
889 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
891 /* Add common actions */
892 gtk_action_group_add_actions (action_group,
893 modest_msg_edit_action_entries,
894 G_N_ELEMENTS (modest_msg_edit_action_entries),
896 gtk_action_group_add_toggle_actions (action_group,
897 modest_msg_edit_toggle_action_entries,
898 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
900 gtk_action_group_add_radio_actions (action_group,
901 modest_msg_edit_alignment_radio_action_entries,
902 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
904 G_CALLBACK (modest_ui_actions_on_change_justify),
906 gtk_action_group_add_radio_actions (action_group,
907 modest_msg_edit_zoom_action_entries,
908 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
910 G_CALLBACK (modest_ui_actions_on_change_zoom),
912 gtk_action_group_add_radio_actions (action_group,
913 modest_msg_edit_priority_action_entries,
914 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
916 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
918 gtk_action_group_add_radio_actions (action_group,
919 modest_msg_edit_file_format_action_entries,
920 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
921 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
922 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
924 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
925 g_object_unref (action_group);
927 /* Load the UI definition */
928 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
931 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
932 g_clear_error (&error);
935 /* Add accelerators */
936 gtk_window_add_accel_group (GTK_WINDOW (obj),
937 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
940 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
941 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
944 init_window (MODEST_MSG_EDIT_WINDOW(obj));
946 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
948 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
950 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
952 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
954 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
955 if (account_pair != NULL)
956 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
958 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
960 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
962 /* Set window icon */
963 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
965 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
966 g_object_unref (window_icon);
969 /* Dim at start clipboard actions */
970 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
971 gtk_action_set_sensitive (action, FALSE);
972 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
973 gtk_action_set_sensitive (action, FALSE);
974 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
975 gtk_action_set_sensitive (action, FALSE);
977 /* Update select all */
978 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
979 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
980 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
981 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
982 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
984 /* set initial state of cc and bcc */
985 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
986 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
987 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
988 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
989 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
990 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
992 /* Setup the file format */
993 conf = modest_runtime_get_conf ();
994 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
996 g_clear_error (&error);
997 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
999 file_format = (prefer_formatted) ?
1000 MODEST_FILE_FORMAT_FORMATTED_TEXT :
1001 MODEST_FILE_FORMAT_PLAIN_TEXT;
1002 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
1004 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
1006 return (ModestWindow*) obj;
1010 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1012 GString **string_buffer = (GString **) user_data;
1014 *string_buffer = g_string_append (*string_buffer, buffer);
1020 * @result: A new string which should be freed with g_free().
1023 get_formatted_data (ModestMsgEditWindow *edit_window)
1025 ModestMsgEditWindowPrivate *priv;
1026 GString *string_buffer = g_string_new ("");
1028 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1030 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1032 return g_string_free (string_buffer, FALSE);
1037 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1040 const gchar *account_name;
1041 ModestMsgEditWindowPrivate *priv;
1043 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1045 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1047 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1048 g_return_val_if_fail (account_name, NULL);
1051 /* don't free these (except from) */
1052 data = g_slice_new0 (MsgData);
1053 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1055 data->account_name = g_strdup (account_name);
1056 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1057 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1058 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1059 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1060 if (priv->draft_msg) {
1061 data->draft_msg = g_object_ref (priv->draft_msg);
1063 data->draft_msg = NULL;
1066 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1068 gtk_text_buffer_get_bounds (buf, &b, &e);
1069 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1071 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1072 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1074 data->html_body = NULL;
1076 /* deep-copy the data */
1077 GList *cursor = priv->attachments;
1078 data->attachments = NULL;
1080 if (!(TNY_IS_MIME_PART(cursor->data))) {
1081 g_warning ("strange data in attachment list");
1084 data->attachments = g_list_append (data->attachments,
1085 g_object_ref (cursor->data));
1086 cursor = g_list_next (cursor);
1089 data->priority_flags = priv->priority_flags;
1096 unref_gobject (GObject *obj, gpointer data)
1098 if (!G_IS_OBJECT(obj))
1100 g_object_unref (obj);
1104 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1107 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1115 g_free (data->subject);
1116 g_free (data->plain_body);
1117 g_free (data->html_body);
1118 g_free (data->account_name);
1120 if (data->draft_msg != NULL) {
1121 g_object_unref (data->draft_msg);
1122 data->draft_msg = NULL;
1125 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1126 g_list_free (data->attachments);
1128 g_slice_free (MsgData, data);
1132 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1135 ModestMsgEditWindowPrivate *priv = NULL;
1136 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1138 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1140 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1142 return MODEST_MSG_EDIT_FORMAT_HTML;
1144 return MODEST_MSG_EDIT_FORMAT_TEXT;
1148 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1149 ModestMsgEditFormat format)
1151 ModestMsgEditWindowPrivate *priv;
1153 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1154 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1157 case MODEST_MSG_EDIT_FORMAT_HTML:
1158 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1160 case MODEST_MSG_EDIT_FORMAT_TEXT:
1161 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1164 g_return_if_reached ();
1168 ModestMsgEditFormatState *
1169 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1171 ModestMsgEditFormatState *format_state = NULL;
1172 ModestMsgEditWindowPrivate *priv;
1173 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1175 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1176 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1178 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1180 format_state = g_new0 (ModestMsgEditFormatState, 1);
1181 format_state->bold = buffer_format->bold&0x1;
1182 format_state->italics = buffer_format->italic&0x1;
1183 format_state->bullet = buffer_format->bullet&0x1;
1184 format_state->color = buffer_format->color;
1185 format_state->font_size = buffer_format->font_size;
1186 format_state->font_family = wp_get_font_name (buffer_format->font);
1187 format_state->justification = buffer_format->justification;
1188 g_free (buffer_format);
1190 return format_state;
1195 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1196 const ModestMsgEditFormatState *format_state)
1198 ModestMsgEditWindowPrivate *priv;
1199 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1200 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1201 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1202 g_return_if_fail (format_state != NULL);
1204 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1205 gtk_widget_grab_focus (priv->msg_body);
1206 buffer_format->bold = (format_state->bold != FALSE);
1207 buffer_format->italic = (format_state->italics != FALSE);
1208 buffer_format->color = format_state->color;
1209 buffer_format->font_size = format_state->font_size;
1210 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1211 buffer_format->justification = format_state->justification;
1212 buffer_format->bullet = format_state->bullet;
1214 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1216 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1217 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1218 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1219 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1220 buffer_format->cs.font = (buffer_format->font != current_format->font);
1221 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1222 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1224 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1225 if (buffer_format->cs.bold) {
1226 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1228 if (buffer_format->cs.italic) {
1229 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1231 if (buffer_format->cs.color) {
1232 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1234 if (buffer_format->cs.font_size) {
1235 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, (gpointer) (buffer_format->font_size));
1237 if (buffer_format->cs.justification) {
1238 switch (buffer_format->justification) {
1239 case GTK_JUSTIFY_LEFT:
1240 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1242 case GTK_JUSTIFY_CENTER:
1243 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1245 case GTK_JUSTIFY_RIGHT:
1246 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1253 if (buffer_format->cs.font) {
1254 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, (gpointer) (buffer_format->font));
1256 if (buffer_format->cs.bullet) {
1257 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1259 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1260 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1262 g_free (current_format);
1267 toggle_action_set_active_block_notify (GtkToggleAction *action,
1270 GSList *proxies = NULL;
1272 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1273 proxies != NULL; proxies = g_slist_next (proxies)) {
1274 GtkWidget *widget = (GtkWidget *) proxies->data;
1275 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1278 gtk_toggle_action_set_active (action, value);
1280 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1281 proxies != NULL; proxies = g_slist_next (proxies)) {
1282 GtkWidget *widget = (GtkWidget *) proxies->data;
1283 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1288 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1290 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1292 ModestWindowPrivate *parent_priv;
1293 ModestMsgEditWindowPrivate *priv;
1294 GtkWidget *new_size_menuitem;
1295 GtkWidget *new_font_menuitem;
1297 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1298 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1300 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1301 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1302 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1303 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1305 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1306 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1307 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1310 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1312 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1313 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1315 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1316 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1318 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1319 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1321 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1322 G_CALLBACK (modest_msg_edit_window_color_button_change),
1324 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1325 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1326 G_CALLBACK (modest_msg_edit_window_color_button_change),
1329 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1330 buffer_format->font_size))->data);
1331 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1335 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1336 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1337 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1339 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1340 G_CALLBACK (modest_msg_edit_window_size_change),
1342 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1343 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1344 G_CALLBACK (modest_msg_edit_window_size_change),
1348 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1349 buffer_format->font))->data);
1350 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1354 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1355 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1356 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1358 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1359 G_CALLBACK (modest_msg_edit_window_font_change),
1361 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1362 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1363 G_CALLBACK (modest_msg_edit_window_font_change),
1367 g_free (buffer_format);
1373 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1376 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1377 ModestMsgEditWindowPrivate *priv;
1378 GtkWidget *dialog = NULL;
1380 const GdkColor *new_color = NULL;
1382 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1383 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1385 #ifdef MODEST_HILDON_VERSION_0
1386 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1387 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1389 dialog = hildon_color_chooser_new ();
1390 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1391 #endif /*MODEST_HILDON_VERSION_0*/
1392 g_free (buffer_format);
1394 response = gtk_dialog_run (GTK_DIALOG (dialog));
1396 case GTK_RESPONSE_OK: {
1397 #ifdef MODEST_HILDON_VERSION_0
1398 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1401 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1403 #endif /*MODEST_HILDON_VERSION_0*/
1410 gtk_widget_destroy (dialog);
1412 if (new_color != NULL)
1413 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1418 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1421 ModestMsgEditWindowPrivate *priv;
1422 GtkWidget *dialog = NULL;
1424 GdkColor *old_color = NULL;
1425 const GdkColor *new_color = NULL;
1427 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1428 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1430 #ifdef MODEST_HILDON_VERSION_0
1431 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1432 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1434 dialog = hildon_color_chooser_new ();
1435 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1436 #endif /*MODEST_HILDON_VERSION_9*/
1438 response = gtk_dialog_run (GTK_DIALOG (dialog));
1440 case GTK_RESPONSE_OK: {
1441 #ifdef MODEST_HILDON_VERSION_0
1442 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1445 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1447 #endif /*MODEST_HILDON_VERSION_0*/
1453 gtk_widget_destroy (dialog);
1455 if (new_color != NULL)
1456 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1462 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1465 ModestMsgEditWindowPrivate *priv;
1466 GtkWidget *dialog = NULL;
1468 GSList *uris = NULL;
1469 GSList *uri_node = NULL;
1471 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1473 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1474 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1475 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1477 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1479 response = gtk_dialog_run (GTK_DIALOG (dialog));
1481 case GTK_RESPONSE_OK:
1482 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1487 gtk_widget_destroy (dialog);
1489 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1491 GnomeVFSHandle *handle = NULL;
1492 GnomeVFSResult result;
1493 GtkTextIter position;
1494 GtkTextMark *insert_mark;
1496 uri = (const gchar *) uri_node->data;
1497 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1498 if (result == GNOME_VFS_OK) {
1499 GdkPixbufLoader *loader;
1501 GnomeVFSFileInfo info;
1502 gchar *filename, *basename, *escaped_filename;
1503 TnyMimePart *mime_part;
1506 const gchar *mime_type = NULL;
1507 GnomeVFSURI *vfs_uri;
1509 vfs_uri = gnome_vfs_uri_new (uri);
1511 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
1512 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
1513 g_free (escaped_filename);
1514 gnome_vfs_uri_unref (vfs_uri);
1516 if (gnome_vfs_get_file_info (uri, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
1517 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
1519 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1521 mime_part = tny_platform_factory_new_mime_part
1522 (modest_runtime_get_platform_factory ());
1523 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1525 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1527 content_id = g_strdup_printf ("%d", priv->last_cid);
1528 tny_mime_part_set_content_id (mime_part, content_id);
1529 g_free (content_id);
1532 basename = g_path_get_basename (filename);
1533 tny_mime_part_set_filename (mime_part, basename);
1536 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1537 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1539 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1540 gtk_widget_show_all (priv->attachments_caption);
1541 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1544 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1545 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1546 unsigned char read_buffer[128];
1548 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1549 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1552 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1553 g_object_ref (pixbuf);
1554 gdk_pixbuf_loader_close (loader, NULL);
1555 g_object_unref (loader);
1557 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1558 GdkPixbuf *new_pixbuf;
1560 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1561 gdk_pixbuf_get_width (pixbuf);
1562 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1563 g_object_unref (pixbuf);
1564 pixbuf = new_pixbuf;
1567 if (pixbuf != NULL) {
1568 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1569 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1570 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1579 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1582 ModestMsgEditWindowPrivate *priv;
1583 GtkWidget *dialog = NULL;
1585 GSList *uris = NULL;
1588 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1590 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1591 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
1592 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1594 response = gtk_dialog_run (GTK_DIALOG (dialog));
1596 case GTK_RESPONSE_OK:
1597 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1602 gtk_widget_destroy (dialog);
1604 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1606 GnomeVFSHandle *handle = NULL;
1607 GnomeVFSResult result;
1609 uri = (const gchar *) uri_node->data;
1610 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1611 if (result == GNOME_VFS_OK) {
1612 TnyMimePart *mime_part;
1614 const gchar *mime_type = NULL;
1616 gchar *escaped_filename;
1619 GnomeVFSFileInfo info;
1620 GnomeVFSURI *vfs_uri;
1622 vfs_uri = gnome_vfs_uri_new (uri);
1625 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
1626 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
1627 g_free (escaped_filename);
1628 gnome_vfs_uri_unref (vfs_uri);
1630 if (gnome_vfs_get_file_info (uri,
1632 GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
1633 GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
1635 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1636 mime_part = tny_platform_factory_new_mime_part
1637 (modest_runtime_get_platform_factory ());
1638 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1640 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1642 content_id = g_strdup_printf ("%d", priv->last_cid);
1643 tny_mime_part_set_content_id (mime_part, content_id);
1644 g_free (content_id);
1647 basename = g_path_get_basename (filename);
1648 tny_mime_part_set_filename (mime_part, basename);
1651 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1652 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1654 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1655 gtk_widget_show_all (priv->attachments_caption);
1656 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1661 g_slist_foreach (uris, (GFunc) g_free, NULL);
1662 g_slist_free (uris);
1666 modest_msg_edit_window_attach_file_noninteractive (
1667 ModestMsgEditWindow *window,
1668 const gchar *file_uri)
1671 ModestMsgEditWindowPrivate *priv;
1673 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1675 if (file_uri && strlen(file_uri)) {
1678 /* TODO: We should probably try to use only the URI,
1679 * instead of using a filename.
1681 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1683 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1686 file_id = g_open (filename, O_RDONLY, 0);
1687 if (file_id != -1) {
1688 TnyMimePart *mime_part;
1690 const gchar *mime_type;
1693 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1694 mime_type = gnome_vfs_get_mime_type(filename);
1696 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1698 mime_part = tny_platform_factory_new_mime_part
1699 (modest_runtime_get_platform_factory ());
1700 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1702 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1704 content_id = g_strdup_printf ("%d", priv->last_cid);
1705 tny_mime_part_set_content_id (mime_part, content_id);
1706 g_free (content_id);
1709 basename = g_path_get_basename (filename);
1710 tny_mime_part_set_filename (mime_part, basename);
1713 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1714 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1716 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1717 gtk_widget_show_all (priv->attachments_caption);
1718 } else if (file_id == -1) {
1720 g_warning("file to be attached does not exist: %s", filename);
1728 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1731 ModestMsgEditWindowPrivate *priv;
1732 gboolean clean_list = FALSE;
1734 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1735 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1737 if (att_list == NULL) {
1738 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1742 if (att_list == NULL) {
1743 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1745 GtkWidget *confirmation_dialog = NULL;
1746 gboolean dialog_response;
1748 gchar *message = NULL;
1749 const gchar *filename = NULL;
1751 if (att_list->next == NULL) {
1752 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1756 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1757 att_list->next == NULL), filename);
1758 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1760 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1761 gtk_widget_destroy (confirmation_dialog);
1762 if (!dialog_response) {
1764 g_list_free (att_list);
1767 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1769 for (node = att_list; node != NULL; node = g_list_next (node)) {
1770 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1771 const gchar *att_id;
1772 priv->attachments = g_list_remove (priv->attachments, mime_part);
1774 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1776 if (priv->attachments == NULL)
1777 gtk_widget_hide (priv->attachments_caption);
1778 att_id = tny_mime_part_get_content_id (mime_part);
1780 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1782 g_object_unref (mime_part);
1783 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1788 g_list_free (att_list);
1792 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1795 ModestMsgEditWindowPrivate *priv;
1796 GdkColor *new_color;
1797 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1799 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1800 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1803 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1805 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1807 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1809 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1814 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1817 ModestMsgEditWindowPrivate *priv;
1818 gint new_size_index;
1819 ModestMsgEditWindow *window;
1822 window = MODEST_MSG_EDIT_WINDOW (userdata);
1823 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1824 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1826 if (gtk_check_menu_item_get_active (menu_item)) {
1828 WPTextBufferFormat format;
1830 memset (&format, 0, sizeof (format));
1831 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
1833 label = gtk_bin_get_child (GTK_BIN (menu_item));
1835 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1836 format.cs.font_size = TRUE;
1837 format.cs.text_position = TRUE;
1838 format.cs.font = TRUE;
1839 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1840 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
1842 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1843 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1844 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1846 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1847 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1848 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1854 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1857 ModestMsgEditWindowPrivate *priv;
1858 gint new_font_index;
1859 ModestMsgEditWindow *window;
1862 window = MODEST_MSG_EDIT_WINDOW (userdata);
1863 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1864 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1866 if (gtk_check_menu_item_get_active (menu_item)) {
1869 label = gtk_bin_get_child (GTK_BIN (menu_item));
1871 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1873 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1874 (gpointer) new_font_index))
1875 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1877 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1878 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1879 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1885 modest_msg_edit_window_set_zoom (ModestWindow *window,
1888 ModestMsgEditWindowPrivate *priv;
1889 ModestWindowPrivate *parent_priv;
1890 GtkRadioAction *zoom_radio_action;
1892 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1894 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1895 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1896 priv->zoom_level = zoom;
1897 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom*DEFAULT_FONT_SCALE);
1899 /* Zoom level menu options should be updated with the current zoom level */
1900 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1901 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1902 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1903 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1904 /* FIXME: Not availible before Gtk 2.10 */
1906 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1911 modest_msg_edit_window_get_zoom (ModestWindow *window)
1913 ModestMsgEditWindowPrivate *priv;
1915 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1917 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1918 return priv->zoom_level;
1922 zoom_allowed (ModestMsgEditWindow *window)
1926 focus = gtk_window_get_focus (GTK_WINDOW (window));
1927 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1931 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1933 ModestWindowPrivate *parent_priv;
1934 GtkRadioAction *zoom_radio_action;
1935 GSList *group, *node;
1937 /* First we check if the text view is focused. If not, zooming is not allowed */
1938 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1939 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1943 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1944 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1945 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1947 group = gtk_radio_action_get_group (zoom_radio_action);
1949 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1950 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1954 for (node = group; node != NULL; node = g_slist_next (node)) {
1955 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1956 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1964 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1966 ModestWindowPrivate *parent_priv;
1967 GtkRadioAction *zoom_radio_action;
1968 GSList *group, *node;
1970 /* First we check if the text view is focused. If not, zooming is not allowed */
1971 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1972 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1976 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1977 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1978 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1980 group = gtk_radio_action_get_group (zoom_radio_action);
1982 for (node = group; node != NULL; node = g_slist_next (node)) {
1983 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1984 if (node->next != NULL) {
1985 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1988 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1996 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1998 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1999 ModestWindowPrivate *parent_priv;
2000 ModestWindowMgr *mgr;
2001 gboolean is_fullscreen;
2002 GtkAction *fs_toggle_action;
2005 mgr = modest_runtime_get_window_mgr ();
2006 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
2008 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
2010 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2011 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2012 if (is_fullscreen != active)
2013 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2021 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
2023 ModestWindowPrivate *parent_priv;
2024 GtkAction *fs_toggle_action;
2027 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2029 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2030 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
2031 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
2035 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2038 ModestMsgEditWindowPrivate *priv = NULL;
2039 const gchar *recipients;
2040 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2042 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2043 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2044 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
2045 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2046 gtk_widget_show (priv->cc_caption);
2048 gtk_widget_hide (priv->cc_caption);
2049 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2053 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2056 ModestMsgEditWindowPrivate *priv = NULL;
2057 const gchar *recipients;
2058 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2060 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2061 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2062 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2063 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2064 gtk_widget_show (priv->bcc_caption);
2066 gtk_widget_hide (priv->bcc_caption);
2067 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2071 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2072 ModestRecptEditor *editor)
2074 ModestMsgEditWindowPrivate *priv;
2076 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2077 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2078 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2080 if (editor == NULL) {
2081 GtkWidget *view_focus;
2082 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2084 /* This code should be kept in sync with ModestRecptEditor. The
2085 textview inside the recpt editor is the one that really gets the
2086 focus. As it's inside a scrolled window, and this one inside the
2087 hbox recpt editor inherits from, we'll need to go up in the
2088 hierarchy to know if the text view is part of the recpt editor
2089 or if it's a different text entry */
2091 if (gtk_widget_get_parent (view_focus)) {
2092 GtkWidget *first_parent;
2094 first_parent = gtk_widget_get_parent (view_focus);
2095 if (gtk_widget_get_parent (first_parent) &&
2096 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2097 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2102 editor = MODEST_RECPT_EDITOR (priv->to_field);
2106 modest_address_book_select_addresses (editor);
2111 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2113 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2115 modest_msg_edit_window_open_addressbook (window, NULL);
2119 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2120 gboolean show_toolbar)
2122 ModestWindowPrivate *parent_priv;
2124 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2125 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2127 /* FIXME: we can not just use the code of
2128 modest_msg_edit_window_setup_toolbar because it has a
2129 mixture of both initialization and creation code. */
2132 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2134 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2138 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2139 TnyHeaderFlags priority_flags)
2141 ModestMsgEditWindowPrivate *priv;
2142 ModestWindowPrivate *parent_priv;
2144 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2146 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2147 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2148 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2150 if (priv->priority_flags != priority_flags) {
2151 GtkAction *priority_action = NULL;
2153 priv->priority_flags = priority_flags;
2155 switch (priority_flags) {
2156 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2157 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2158 gtk_widget_show (priv->priority_icon);
2159 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2160 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2162 case TNY_HEADER_FLAG_LOW_PRIORITY:
2163 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", 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/MessagePriorityLowMenu");
2169 gtk_widget_hide (priv->priority_icon);
2170 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2171 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2174 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2175 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2180 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2183 ModestMsgEditWindowPrivate *priv;
2184 ModestWindowPrivate *parent_priv;
2185 gint current_format;
2187 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2189 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2190 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2192 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2193 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2195 if (current_format != file_format) {
2196 switch (file_format) {
2197 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2198 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2200 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2204 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2205 response = gtk_dialog_run (GTK_DIALOG (dialog));
2206 gtk_widget_destroy (dialog);
2207 if (response == GTK_RESPONSE_OK) {
2208 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2210 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2211 toggle_action_set_active_block_notify (action, TRUE);
2216 update_dimmed (window);
2221 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2224 ModestMsgEditWindowPrivate *priv;
2225 WPTextBufferFormat oldfmt, fmt;
2226 gint old_position = 0;
2230 GdkColor *color = NULL;
2231 gboolean bold, bold_set, italic, italic_set;
2232 gboolean underline, underline_set;
2233 gboolean strikethrough, strikethrough_set;
2234 gboolean position_set;
2235 gboolean font_size_set, font_set, color_set;
2238 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2239 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2241 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2243 /* First we get the currently selected font information */
2244 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2245 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2247 switch (oldfmt.text_position) {
2248 case TEXT_POSITION_NORMAL:
2251 case TEXT_POSITION_SUPERSCRIPT:
2259 g_object_set (G_OBJECT (dialog),
2260 "bold", oldfmt.bold != FALSE,
2261 "bold-set", !oldfmt.cs.bold,
2262 "underline", oldfmt.underline != FALSE,
2263 "underline-set", !oldfmt.cs.underline,
2264 "italic", oldfmt.italic != FALSE,
2265 "italic-set", !oldfmt.cs.italic,
2266 "strikethrough", oldfmt.strikethrough != FALSE,
2267 "strikethrough-set", !oldfmt.cs.strikethrough,
2268 "color", &oldfmt.color,
2269 "color-set", !oldfmt.cs.color,
2270 "size", wp_font_size[oldfmt.font_size],
2271 "size-set", !oldfmt.cs.font_size,
2272 "position", old_position,
2273 "position-set", !oldfmt.cs.text_position,
2274 "family", wp_get_font_name (oldfmt.font),
2275 "family-set", !oldfmt.cs.font,
2278 gtk_widget_show_all (dialog);
2279 response = gtk_dialog_run (GTK_DIALOG (dialog));
2280 if (response == GTK_RESPONSE_OK) {
2282 g_object_get( dialog,
2284 "bold-set", &bold_set,
2285 "underline", &underline,
2286 "underline-set", &underline_set,
2288 "italic-set", &italic_set,
2289 "strikethrough", &strikethrough,
2290 "strikethrough-set", &strikethrough_set,
2292 "color-set", &color_set,
2294 "size-set", &font_size_set,
2295 "family", &font_name,
2296 "family-set", &font_set,
2297 "position", &position,
2298 "position-set", &position_set,
2303 if (response == GTK_RESPONSE_OK) {
2304 memset(&fmt, 0, sizeof(fmt));
2310 fmt.italic = italic;
2311 fmt.cs.italic = TRUE;
2313 if (underline_set) {
2314 fmt.underline = underline;
2315 fmt.cs.underline = TRUE;
2317 if (strikethrough_set) {
2318 fmt.strikethrough = strikethrough;
2319 fmt.cs.strikethrough = TRUE;
2324 ? TEXT_POSITION_NORMAL
2325 : ( ( position == 1 )
2326 ? TEXT_POSITION_SUPERSCRIPT
2327 : TEXT_POSITION_SUBSCRIPT );
2328 fmt.cs.text_position = TRUE;
2332 fmt.cs.color = TRUE;
2335 fmt.font = wp_get_font_index(font_name,
2340 if (font_size_set) {
2341 fmt.font_size = wp_get_font_size_index(
2342 font_size, DEFAULT_FONT_SIZE);
2343 fmt.cs.font_size = TRUE;
2345 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2347 gtk_widget_destroy (dialog);
2349 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2353 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2355 ModestMsgEditWindowPrivate *priv;
2357 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2358 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2360 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2362 update_dimmed (window);
2367 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2369 ModestMsgEditWindowPrivate *priv;
2371 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2372 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2374 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2376 update_dimmed (window);
2381 update_dimmed (ModestMsgEditWindow *window)
2383 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2384 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2388 gboolean editor_focused;
2390 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2391 editor_focused = gtk_widget_is_focus (priv->msg_body);
2393 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2394 gtk_action_set_sensitive (action, rich_text && editor_focused);
2395 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2396 gtk_action_set_sensitive (action, rich_text && editor_focused);
2397 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2398 gtk_action_set_sensitive (action, rich_text && editor_focused);
2399 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2400 gtk_action_set_sensitive (action, rich_text && editor_focused);
2401 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2402 gtk_action_set_sensitive (action, rich_text && editor_focused);
2403 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2404 gtk_action_set_sensitive (action, rich_text && editor_focused);
2405 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2406 gtk_action_set_sensitive (action, rich_text && editor_focused);
2407 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2408 gtk_action_set_sensitive (action, rich_text && editor_focused);
2409 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2410 gtk_action_set_sensitive (action, rich_text && editor_focused);
2411 widget = priv->font_color_button;
2412 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2413 widget = priv->font_size_toolitem;
2414 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2415 widget = priv->font_face_toolitem;
2416 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2420 setup_insensitive_handlers (ModestMsgEditWindow *window)
2422 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2423 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2426 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2427 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2428 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2429 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2430 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2431 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2432 widget = priv->font_color_button;
2433 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2434 widget = priv->font_size_toolitem;
2435 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2436 widget = priv->font_face_toolitem;
2437 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2442 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2444 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2447 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2448 gtk_action_set_sensitive (action, can_undo);
2452 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2454 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2457 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu");
2458 gtk_action_set_sensitive (action, can_redo);
2462 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2465 GtkTextIter match_start, match_end;
2467 if (image_id == NULL)
2470 gtk_text_buffer_get_start_iter (buffer, &iter);
2472 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2473 GSList *tags = gtk_text_iter_get_tags (&match_start);
2475 for (node = tags; node != NULL; node = g_slist_next (node)) {
2476 GtkTextTag *tag = (GtkTextTag *) node->data;
2477 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2478 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2479 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2481 offset = gtk_text_iter_get_offset (&match_start);
2482 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2483 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2487 gtk_text_iter_forward_char (&iter);
2492 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2494 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2495 GtkTextIter real_start, real_end;
2496 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2498 if (gtk_text_iter_compare (start, end) > 0) {
2502 real_start = *start;
2506 GSList *tags = gtk_text_iter_get_tags (&real_start);
2508 for (node = tags; node != NULL; node = g_slist_next (node)) {
2509 GtkTextTag *tag = (GtkTextTag *) node->data;
2510 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2511 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2513 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2515 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2518 } while (gtk_text_iter_forward_char (&real_start)&&
2519 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2523 msg_body_focus (GtkWidget *focus,
2524 GdkEventFocus *event,
2528 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2533 recpt_field_changed (GtkTextBuffer *buffer,
2534 ModestMsgEditWindow *editor)
2536 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2537 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2538 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2539 gboolean dim = FALSE;
2542 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2543 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2544 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2546 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2547 gtk_text_buffer_get_char_count (cc_buffer) +
2548 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2550 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2551 gtk_action_set_sensitive (action, !dim);
2552 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2553 gtk_action_set_sensitive (action, !dim);
2557 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2559 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2563 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2565 gboolean rich_text, editor_focused;
2567 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2568 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2569 editor_focused = gtk_widget_is_focus (priv->msg_body);
2572 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2573 else if (!editor_focused)
2574 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2578 reset_modified (ModestMsgEditWindow *editor)
2580 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2581 GtkTextBuffer *buffer;
2583 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2584 gtk_text_buffer_set_modified (buffer, FALSE);
2585 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2586 gtk_text_buffer_set_modified (buffer, FALSE);
2587 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2588 gtk_text_buffer_set_modified (buffer, FALSE);
2589 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2593 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2595 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2596 GtkTextBuffer *buffer;
2598 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2599 if (gtk_text_buffer_get_modified (buffer))
2601 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2602 if (gtk_text_buffer_get_modified (buffer))
2604 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2605 if (gtk_text_buffer_get_modified (buffer))
2607 if (gtk_text_buffer_get_modified (priv->text_buffer))
2614 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2616 ModestMsgEditWindowPrivate *priv = NULL;
2618 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2619 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2621 /* check if there's no recipient added */
2622 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2623 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2624 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2625 /* no recipient contents, then select contacts */
2626 modest_msg_edit_window_open_addressbook (window, NULL);
2630 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2632 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2634 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2637 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2644 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2645 ModestMsgEditWindow *window)
2647 modest_msg_edit_window_attach_file (window);
2651 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2653 ModestMsgEditWindow *window)
2655 ModestWindowPrivate *parent_priv;
2656 ModestMsgEditWindowPrivate *priv;
2658 gboolean has_selection;
2660 GList *selected_attachments = NULL;
2661 gint n_att_selected = 0;
2663 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2664 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2665 has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL);
2666 focused = gtk_window_get_focus (GTK_WINDOW (window));
2668 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2669 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2670 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2671 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2673 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2674 n_att_selected = g_list_length (selected_attachments);
2675 g_list_free (selected_attachments);
2677 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2678 gtk_action_set_sensitive (action, n_att_selected == 1);
2680 update_paste_dimming (window);
2684 update_window_title (ModestMsgEditWindow *window)
2686 ModestMsgEditWindowPrivate *priv = NULL;
2687 const gchar *subject;
2689 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2690 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2691 if (subject == NULL || subject[0] == '\0')
2692 subject = _("mail_va_new_email");
2694 gtk_window_set_title (GTK_WINDOW (window), subject);
2699 subject_field_changed (GtkEditable *editable,
2700 ModestMsgEditWindow *window)
2702 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2703 update_window_title (window);
2704 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2708 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2711 ModestMsgEditWindowPrivate *priv = NULL;
2713 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2714 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2716 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2718 gtk_widget_show_all (priv->find_toolbar);
2719 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2721 gtk_widget_hide_all (priv->find_toolbar);
2722 gtk_widget_grab_focus (priv->msg_body);
2728 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2730 GtkTextIter *match_start,
2731 GtkTextIter *match_end)
2733 GtkTextIter end_iter;
2734 gchar *str_casefold;
2737 gchar *range_casefold;
2740 gboolean result = FALSE;
2747 gtk_text_iter_forward_to_end (&end_iter);
2749 str_casefold = g_utf8_casefold (str, -1);
2750 str_chars_n = strlen (str);
2752 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2753 range_casefold = g_utf8_casefold (range_text, -1);
2754 range_chars_n = strlen (range_casefold);
2756 if (range_chars_n < str_chars_n) {
2757 g_free (str_casefold);
2758 g_free (range_text);
2759 g_free (range_casefold);
2763 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2764 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2765 if (!g_utf8_collate (range_subtext, str_casefold)) {
2766 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2768 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2769 match_start, match_end, NULL);
2770 g_free (found_text);
2772 g_free (range_subtext);
2776 g_free (str_casefold);
2777 g_free (range_text);
2778 g_free (range_casefold);
2785 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2786 ModestMsgEditWindow *window)
2788 gchar *current_search = NULL;
2789 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2791 GtkTextIter selection_start, selection_end;
2792 GtkTextIter match_start, match_end;
2793 gboolean continue_search = FALSE;
2795 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2796 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2797 g_free (current_search);
2798 g_free (priv->last_search);
2799 priv->last_search = NULL;
2800 /* Information banner about empty search */
2801 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2805 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2806 continue_search = TRUE;
2808 g_free (priv->last_search);
2809 priv->last_search = g_strdup (current_search);
2812 if (continue_search) {
2813 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2814 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2815 &match_start, &match_end);
2817 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2819 GtkTextIter buffer_start;
2820 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2821 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2822 &match_start, &match_end);
2824 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2827 /* Mark as selected the string found in search */
2829 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2830 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2832 g_free (priv->last_search);
2833 priv->last_search = NULL;
2835 g_free (current_search);
2839 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2840 ModestMsgEditWindow *window)
2842 GtkToggleAction *toggle;
2843 ModestWindowPrivate *parent_priv;
2844 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2846 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2847 gtk_toggle_action_set_active (toggle, FALSE);
2852 update_paste_dimming (ModestMsgEditWindow *window)
2854 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2855 GtkAction *action = NULL;
2856 GtkClipboard *clipboard = NULL;
2860 focused = gtk_window_get_focus (GTK_WINDOW (window));
2862 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2863 active = gtk_clipboard_wait_is_text_available (clipboard);
2866 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2870 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2871 gtk_action_set_sensitive (action, active);
2876 update_select_all_dimming (ModestMsgEditWindow *window)
2879 gboolean dimmed = FALSE;
2881 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2883 focused = gtk_window_get_focus (GTK_WINDOW (window));
2884 if (GTK_IS_ENTRY (focused)) {
2885 const gchar *current_text;
2886 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2887 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2888 } else if (GTK_IS_TEXT_VIEW (focused)) {
2889 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2890 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2891 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2894 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2895 gtk_action_set_sensitive (action, !dimmed);
2899 update_zoom_dimming (ModestMsgEditWindow *window)
2902 gboolean dimmed = FALSE;
2904 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2906 focused = gtk_window_get_focus (GTK_WINDOW (window));
2907 dimmed = ! WP_IS_TEXT_VIEW (focused);
2908 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2909 gtk_action_set_sensitive (action, !dimmed);
2913 edit_menu_activated (GtkAction *action,
2916 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2918 update_select_all_dimming (window);
2919 update_paste_dimming (window);
2922 view_menu_activated (GtkAction *action,
2925 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2927 update_zoom_dimming (window);
2931 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2933 ModestMsgEditWindowPrivate *priv;
2935 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2940 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
2943 ModestMsgEditWindowPrivate *priv;
2945 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2951 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
2954 ModestMsgEditWindowPrivate *priv;
2955 TnyHeader *header = NULL;
2957 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2958 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
2960 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2961 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
2963 if (priv->draft_msg != NULL) {
2964 header = tny_msg_get_header (priv->draft_msg);
2965 if (TNY_IS_HEADER (header)) {
2966 modest_window_mgr_unregister_header (mgr, header);
2968 g_object_unref (priv->draft_msg);
2971 if (draft != NULL) {
2972 g_object_ref (draft);
2973 header = tny_msg_get_header (draft);
2974 if (TNY_IS_HEADER (header))
2975 modest_window_mgr_register_header (mgr, header);
2978 priv->draft_msg = draft;