1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37 #include <tny-vfs-stream.h>
41 #include <modest-account-mgr.h>
42 #include <modest-account-mgr-helpers.h>
44 #include <widgets/modest-msg-edit-window.h>
45 #include <widgets/modest-combo-box.h>
46 #include <widgets/modest-recpt-editor.h>
47 #include <widgets/modest-attachments-view.h>
49 #include <modest-runtime.h>
51 #include "modest-platform.h"
52 #include "modest-icon-names.h"
53 #include "modest-widget-memory.h"
54 #include "modest-window-priv.h"
55 #include "modest-mail-operation.h"
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-tny-folder.h"
59 #include "modest-address-book.h"
60 #include "modest-text-utils.h"
61 #include <tny-simple-list.h>
62 #include <wptextview.h>
63 #include <wptextbuffer.h>
64 #include "modest-scroll-area.h"
66 #include "modest-hildon-includes.h"
67 #ifdef MODEST_HAVE_HILDON0_WIDGETS
68 #include <hildon-widgets/hildon-color-chooser.h>
70 #include "widgets/modest-msg-edit-window-ui.h"
71 #ifdef MODEST_HAVE_HILDON0_WIDGETS
72 #include <libgnomevfs/gnome-vfs-mime-utils.h>
74 #include <libgnomevfs/gnome-vfs-mime.h>
76 #include "modest-maemo-utils.h"
79 #define DEFAULT_FONT_SIZE 3
80 #define DEFAULT_FONT 2
81 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
82 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
83 #define DEFAULT_MAIN_VBOX_SPACING 6
84 #define SUBJECT_MAX_LENGTH 1000
85 #define IMAGE_MAX_WIDTH 640
86 #define DEFAULT_FONT_SCALE 1.5
88 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
89 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
90 static void modest_msg_edit_window_finalize (GObject *obj);
92 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
93 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
94 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
95 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
96 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
97 static void reset_modified (ModestMsgEditWindow *editor);
99 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
100 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
101 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
102 static void text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window);
103 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
104 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
105 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
107 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
109 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
111 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
112 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
113 GdkEventWindowState *event,
115 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
116 ModestRecptEditor *editor);
117 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
118 ModestMsgEditWindow *window);
120 /* ModestWindow methods implementation */
121 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
122 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
123 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
124 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
125 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
126 gboolean show_toolbar);
127 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
129 ModestMsgEditWindow *window);
130 static void update_window_title (ModestMsgEditWindow *window);
131 static void update_dimmed (ModestMsgEditWindow *window);
132 static void update_paste_dimming (ModestMsgEditWindow *window);
133 static void update_select_all_dimming (ModestMsgEditWindow *window);
134 static void update_zoom_dimming (ModestMsgEditWindow *window);
137 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
138 ModestMsgEditWindow *window);
139 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
140 ModestMsgEditWindow *window);
141 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
143 GtkTextIter *match_start,
144 GtkTextIter *match_end);
148 /* static gboolean */
149 /* on_key_pressed (GtkWidget *self, */
150 /* GdkEventKey *event, */
151 /* gpointer user_data); */
153 static void edit_menu_activated (GtkAction *action,
155 static void view_menu_activated (GtkAction *action,
158 /* list my signals */
165 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
166 struct _ModestMsgEditWindowPrivate {
168 GtkWidget *header_box;
170 ModestPairList *from_field_protos;
171 GtkWidget *from_field;
175 GtkWidget *bcc_field;
176 GtkWidget *subject_field;
177 GtkWidget *attachments_view;
178 GtkWidget *priority_icon;
179 GtkWidget *add_attachment_button;
181 GtkWidget *cc_caption;
182 GtkWidget *bcc_caption;
183 GtkWidget *attachments_caption;
185 GtkTextBuffer *text_buffer;
187 GtkWidget *font_size_toolitem;
188 GtkWidget *font_face_toolitem;
189 GtkWidget *font_color_button;
190 GSList *font_items_group;
191 GtkWidget *font_tool_button_label;
192 GSList *size_items_group;
193 GtkWidget *size_tool_button_label;
195 GtkWidget *find_toolbar;
199 GtkWidget *scroll_area;
204 TnyHeaderFlags priority_flags;
208 gulong clipboard_change_handler_id;
214 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
215 MODEST_TYPE_MSG_EDIT_WINDOW, \
216 ModestMsgEditWindowPrivate))
218 static GtkWindowClass *parent_class = NULL;
220 /* uncomment the following if you have defined any signals */
221 /* static guint signals[LAST_SIGNAL] = {0}; */
224 modest_msg_edit_window_get_type (void)
226 static GType my_type = 0;
228 static const GTypeInfo my_info = {
229 sizeof(ModestMsgEditWindowClass),
230 NULL, /* base init */
231 NULL, /* base finalize */
232 (GClassInitFunc) modest_msg_edit_window_class_init,
233 NULL, /* class finalize */
234 NULL, /* class data */
235 sizeof(ModestMsgEditWindow),
237 (GInstanceInitFunc) modest_msg_edit_window_init,
240 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
241 "ModestMsgEditWindow",
244 wp_text_buffer_library_init ();
250 save_state (ModestWindow *self)
252 modest_widget_memory_save (modest_runtime_get_conf(),
253 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
258 restore_settings (ModestMsgEditWindow *self)
260 modest_widget_memory_restore (modest_runtime_get_conf(),
261 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
266 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
268 GObjectClass *gobject_class;
269 ModestWindowClass *modest_window_class;
270 gobject_class = (GObjectClass*) klass;
271 modest_window_class = (ModestWindowClass*) klass;
273 parent_class = g_type_class_peek_parent (klass);
274 gobject_class->finalize = modest_msg_edit_window_finalize;
276 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
277 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
278 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
279 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
280 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
281 modest_window_class->save_state_func = save_state;
283 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
289 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
291 ModestMsgEditWindowPrivate *priv;
292 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
294 priv->msg_body = NULL;
295 priv->from_field = NULL;
296 priv->to_field = NULL;
297 priv->cc_field = NULL;
298 priv->bcc_field = NULL;
299 priv->subject_field = NULL;
300 priv->attachments = NULL;
302 priv->zoom_level = 1.0;
304 priv->cc_caption = NULL;
305 priv->bcc_caption = NULL;
307 priv->priority_flags = 0;
309 priv->find_toolbar = NULL;
310 priv->last_search = NULL;
312 priv->draft_msg = NULL;
313 priv->clipboard_change_handler_id = 0;
318 /* FIXME: this is a dup from the one in gtk/ */
321 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
323 static ModestPairList*
324 get_transports (void)
326 GSList *transports = NULL;
328 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
329 GSList *accounts = modest_account_mgr_account_names (account_mgr,
330 TRUE /* only enabled accounts. */);
332 GSList *cursor = accounts;
334 gchar *account_name = cursor->data;
335 gchar *from_string = NULL;
337 from_string = modest_account_mgr_get_from_string (account_mgr,
341 if (from_string && account_name) {
342 gchar *name = account_name;
343 ModestPair *pair = modest_pair_new ((gpointer) name,
344 (gpointer) from_string , TRUE);
345 transports = g_slist_prepend (transports, pair);
348 cursor = cursor->next;
350 g_slist_free (accounts); /* only free the accounts, not the elements,
351 * because they are used in the pairlist */
357 init_window (ModestMsgEditWindow *obj)
359 GtkWidget *from_caption, *to_caption, *subject_caption;
360 GtkWidget *main_vbox;
361 ModestMsgEditWindowPrivate *priv;
363 GtkSizeGroup *size_group;
365 GtkWidget *subject_box;
366 GtkWidget *attachment_icon;
367 GtkWidget *window_box;
369 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
371 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
373 /* Note: This ModestPairList* must exist for as long as the combo
374 * that uses it, because the ModestComboBox uses the ID opaquely,
375 * so it can't know how to manage its memory. */
376 priv->from_field_protos = get_transports ();
378 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
380 priv->to_field = modest_recpt_editor_new ();
381 priv->cc_field = modest_recpt_editor_new ();
382 priv->bcc_field = modest_recpt_editor_new ();
383 subject_box = gtk_hbox_new (FALSE, 0);
384 priv->priority_icon = gtk_image_new ();
385 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
386 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
387 g_object_set (G_OBJECT (priv->subject_field), "truncate-multiline", TRUE, NULL);
388 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
389 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
390 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
391 priv->add_attachment_button = gtk_button_new ();
392 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
393 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
394 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
395 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
396 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
397 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
398 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
399 priv->attachments_view = modest_attachments_view_new (NULL);
401 priv->header_box = gtk_vbox_new (FALSE, 0);
403 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
404 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
405 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
406 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
407 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
408 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
409 g_object_unref (size_group);
411 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
412 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
413 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
414 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
415 gtk_size_group_add_widget (size_group, priv->subject_field);
416 gtk_size_group_add_widget (size_group, priv->attachments_view);
417 g_object_unref (size_group);
419 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
420 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
421 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
422 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
423 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
424 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
425 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
428 priv->msg_body = wp_text_view_new ();
429 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
430 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
431 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
432 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
433 #if (GTK_MINOR_VERSION >= 10)
434 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
435 gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
437 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
439 priv->find_toolbar = hildon_find_toolbar_new (NULL);
440 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
442 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
444 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
445 G_CALLBACK (text_buffer_refresh_attributes), obj);
446 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
447 G_CALLBACK (text_buffer_delete_range), obj);
448 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
449 G_CALLBACK (text_buffer_can_undo), obj);
450 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
451 G_CALLBACK (text_buffer_can_redo), obj);
452 g_signal_connect (G_OBJECT (obj), "window-state-event",
453 G_CALLBACK (modest_msg_edit_window_window_state_event),
455 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
456 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
457 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
458 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
459 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
460 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
462 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
463 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
465 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
466 G_CALLBACK (msg_body_focus), obj);
467 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
468 G_CALLBACK (msg_body_focus), obj);
469 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
470 "changed", G_CALLBACK (recpt_field_changed), obj);
471 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
472 "changed", G_CALLBACK (recpt_field_changed), obj);
473 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
474 "changed", G_CALLBACK (recpt_field_changed), obj);
475 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
476 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
478 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
479 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
481 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
482 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
483 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
484 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->scroll), TRUE);
486 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
488 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
489 frame = gtk_frame_new (NULL);
490 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
492 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
493 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
494 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
496 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
497 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
498 gtk_widget_hide (priv->cc_caption);
500 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
501 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
502 gtk_widget_hide (priv->bcc_caption);
505 window_box = gtk_vbox_new (FALSE, 0);
506 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
507 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
508 gtk_container_add (GTK_CONTAINER(obj), window_box);
509 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
510 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
513 TODO: scroll_area was never instantiated.
514 Stop building without warnings-as-errors. murrayc.
515 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
516 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
519 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
520 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
526 modest_msg_edit_window_finalize (GObject *obj)
528 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
530 if (priv->clipboard_change_handler_id > 0) {
531 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
532 priv->clipboard_change_handler_id = 0;
535 if (priv->draft_msg != NULL) {
536 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
537 if (TNY_IS_HEADER (header)) {
538 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
539 modest_window_mgr_unregister_header (mgr, header);
541 g_object_unref (priv->draft_msg);
542 priv->draft_msg = NULL;
545 /* This had to stay alive for as long as the combobox that used it: */
546 modest_pair_list_free (priv->from_field_protos);
548 G_OBJECT_CLASS(parent_class)->finalize (obj);
552 menubar_to_menu (GtkUIManager *ui_manager)
554 GtkWidget *main_menu;
558 /* Create new main menu */
559 main_menu = gtk_menu_new();
561 /* Get the menubar from the UI manager */
562 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
564 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
568 menu = GTK_WIDGET (iter->data);
569 gtk_widget_reparent(menu, main_menu);
571 iter = g_list_next (iter);
578 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
581 const gchar *to, *cc, *bcc, *subject;
583 ModestMsgEditWindowPrivate *priv;
585 TnyHeaderFlags priority_flags;
586 TnyFolder *msg_folder;
588 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
589 g_return_if_fail (TNY_IS_MSG (msg));
591 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
593 header = tny_msg_get_header (msg);
594 to = tny_header_get_to (header);
595 cc = tny_header_get_cc (header);
596 bcc = tny_header_get_bcc (header);
597 subject = tny_header_get_subject (header);
598 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
601 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
603 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
604 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
605 gtk_widget_show (priv->cc_caption);
606 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
607 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
608 gtk_widget_hide (priv->cc_caption);
611 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
612 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
613 gtk_widget_show (priv->bcc_caption);
614 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
615 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
616 gtk_widget_hide (priv->bcc_caption);
619 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
620 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
623 update_window_title (self);
625 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
626 body = modest_tny_msg_get_body (msg, TRUE);
628 if ((body == NULL)||(body[0] == '\0')) {
630 body = modest_text_utils_convert_to_html ("");
632 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
633 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
636 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
639 /* Get the default format required from configuration */
640 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
641 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
644 /* Set the default focus depending on having already a To: field or not */
645 if ((!to)||(*to == '\0')) {
646 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
648 gtk_widget_grab_focus (priv->msg_body);
651 /* TODO: lower priority, select in the From: combo to the
652 value that comes from msg <- not sure, should it be
655 /* Add attachments to the view */
656 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
657 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
658 if (priv->attachments == NULL) {
659 gtk_widget_hide (priv->attachments_caption);
661 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
662 gtk_widget_show_all (priv->attachments_caption);
665 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
666 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
668 reset_modified (self);
670 update_dimmed (self);
671 text_buffer_can_undo (priv->text_buffer, FALSE, self);
672 text_buffer_can_redo (priv->text_buffer, FALSE, self);
674 /* we should set a reference to the incoming message if it is a draft */
675 msg_folder = tny_msg_get_folder (msg);
677 if (modest_tny_folder_is_local_folder (msg_folder) &&
678 modest_tny_folder_get_local_folder_type (msg_folder) == TNY_FOLDER_TYPE_DRAFTS)
679 priv->draft_msg = g_object_ref(msg);
680 g_object_unref (msg_folder);
685 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
688 GList *item_children, *node;
689 GtkWidget *bin_child;
691 bin_child = gtk_bin_get_child (GTK_BIN(item));
693 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
695 for (node = item_children; node != NULL; node = g_list_next (node)) {
696 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
697 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
700 g_list_free (item_children);
704 menu_tool_button_dont_expand (GtkMenuToolButton *item)
707 GList *item_children, *node;
709 box = gtk_bin_get_child (GTK_BIN (item));
710 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
711 item_children = gtk_container_get_children (GTK_CONTAINER (box));
713 for (node = item_children; node != NULL; node = g_list_next (node)) {
714 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
715 if (GTK_IS_TOGGLE_BUTTON (node->data))
716 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
717 else if (GTK_IS_BUTTON (node->data))
718 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
720 g_list_free (item_children);
725 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
727 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
728 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
729 GtkWidget *placeholder;
730 GtkWidget *tool_item;
735 GtkWidget *sizes_menu;
736 GtkWidget *fonts_menu;
737 GSList *radio_group = NULL;
742 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
743 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
745 /* should we hide the toolbar? */
746 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
747 gtk_widget_hide (parent_priv->toolbar);
749 /* Font color placeholder */
750 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
751 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
754 tool_item = GTK_WIDGET (gtk_tool_item_new ());
755 priv->font_color_button = hildon_color_button_new ();
756 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
757 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
758 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
759 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
760 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
761 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
762 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
764 /* Font size and face placeholder */
765 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
766 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
768 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
769 priv->size_tool_button_label = gtk_label_new (NULL);
770 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
771 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
772 size_text,"</span>", NULL);
773 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
775 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
776 sizes_menu = gtk_menu_new ();
777 priv->size_items_group = NULL;
779 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
780 GtkWidget *size_menu_item;
782 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
783 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
784 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
785 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
786 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
787 gtk_widget_show (size_menu_item);
789 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
793 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
794 GtkWidget *item = (GtkWidget *) node->data;
795 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
799 priv->size_items_group = g_slist_reverse (priv->size_items_group);
800 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
801 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
802 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
803 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
804 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
805 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
806 priv->font_size_toolitem = tool_item;
809 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
810 priv->font_tool_button_label = gtk_label_new (NULL);
811 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
812 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
814 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
815 fonts_menu = gtk_menu_new ();
816 priv->font_items_group = NULL;
818 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
819 GtkWidget *font_menu_item;
820 GtkWidget *child_label;
822 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
823 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
824 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
825 wp_get_font_name (font_index), "</span>", NULL);
826 gtk_label_set_markup (GTK_LABEL (child_label), markup);
829 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
830 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
831 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
832 gtk_widget_show (font_menu_item);
834 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
837 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
838 GtkWidget *item = (GtkWidget *) node->data;
839 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
842 priv->font_items_group = g_slist_reverse (priv->font_items_group);
843 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
844 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
845 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
846 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
847 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
848 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
849 priv->font_face_toolitem = tool_item;
851 /* Set expand and homogeneous for remaining items */
852 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
853 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
854 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
855 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
856 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
857 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
858 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
859 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
860 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
868 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
871 ModestWindowPrivate *parent_priv;
872 ModestMsgEditWindowPrivate *priv;
873 GtkActionGroup *action_group;
874 GError *error = NULL;
875 GdkPixbuf *window_icon = NULL;
878 gboolean prefer_formatted;
880 ModestPair *account_pair = NULL;
882 g_return_val_if_fail (msg, NULL);
883 g_return_val_if_fail (account_name, NULL);
885 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
887 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
888 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
890 parent_priv->ui_manager = gtk_ui_manager_new();
891 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
892 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
894 /* Add common actions */
895 gtk_action_group_add_actions (action_group,
896 modest_msg_edit_action_entries,
897 G_N_ELEMENTS (modest_msg_edit_action_entries),
899 gtk_action_group_add_toggle_actions (action_group,
900 modest_msg_edit_toggle_action_entries,
901 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
903 gtk_action_group_add_radio_actions (action_group,
904 modest_msg_edit_alignment_radio_action_entries,
905 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
907 G_CALLBACK (modest_ui_actions_on_change_justify),
909 gtk_action_group_add_radio_actions (action_group,
910 modest_msg_edit_zoom_action_entries,
911 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
913 G_CALLBACK (modest_ui_actions_on_change_zoom),
915 gtk_action_group_add_radio_actions (action_group,
916 modest_msg_edit_priority_action_entries,
917 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
919 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
921 gtk_action_group_add_radio_actions (action_group,
922 modest_msg_edit_file_format_action_entries,
923 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
924 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
925 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
927 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
928 g_object_unref (action_group);
930 /* Load the UI definition */
931 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
934 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
935 g_clear_error (&error);
938 /* Add accelerators */
939 gtk_window_add_accel_group (GTK_WINDOW (obj),
940 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
943 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
944 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
947 init_window (MODEST_MSG_EDIT_WINDOW(obj));
949 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
951 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
953 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
955 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
957 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
958 if (account_pair != NULL)
959 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
961 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
963 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
965 /* Set window icon */
966 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
968 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
969 g_object_unref (window_icon);
972 /* Dim at start clipboard actions */
973 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
974 gtk_action_set_sensitive (action, FALSE);
975 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
976 gtk_action_set_sensitive (action, FALSE);
977 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
978 gtk_action_set_sensitive (action, FALSE);
980 /* Update select all */
981 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
982 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
983 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
984 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
985 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
987 /* set initial state of cc and bcc */
988 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
989 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
990 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
991 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
992 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
993 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
995 /* Setup the file format */
996 conf = modest_runtime_get_conf ();
997 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
999 g_clear_error (&error);
1000 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
1002 file_format = (prefer_formatted) ?
1003 MODEST_FILE_FORMAT_FORMATTED_TEXT :
1004 MODEST_FILE_FORMAT_PLAIN_TEXT;
1005 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
1007 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
1009 return (ModestWindow*) obj;
1013 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1015 GString **string_buffer = (GString **) user_data;
1017 *string_buffer = g_string_append (*string_buffer, buffer);
1023 * @result: A new string which should be freed with g_free().
1026 get_formatted_data (ModestMsgEditWindow *edit_window)
1028 ModestMsgEditWindowPrivate *priv;
1029 GString *string_buffer = g_string_new ("");
1031 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1033 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1035 return g_string_free (string_buffer, FALSE);
1040 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1043 const gchar *account_name;
1044 ModestMsgEditWindowPrivate *priv;
1046 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1048 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1050 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1051 g_return_val_if_fail (account_name, NULL);
1054 /* don't free these (except from) */
1055 data = g_slice_new0 (MsgData);
1056 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1058 data->account_name = g_strdup (account_name);
1059 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1060 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1061 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1062 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1063 if (priv->draft_msg) {
1064 data->draft_msg = g_object_ref (priv->draft_msg);
1066 data->draft_msg = NULL;
1069 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1071 gtk_text_buffer_get_bounds (buf, &b, &e);
1072 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1074 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1075 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1077 data->html_body = NULL;
1079 /* deep-copy the data */
1080 GList *cursor = priv->attachments;
1081 data->attachments = NULL;
1083 if (!(TNY_IS_MIME_PART(cursor->data))) {
1084 g_warning ("strange data in attachment list");
1087 data->attachments = g_list_append (data->attachments,
1088 g_object_ref (cursor->data));
1089 cursor = g_list_next (cursor);
1092 data->priority_flags = priv->priority_flags;
1099 unref_gobject (GObject *obj, gpointer data)
1101 if (!G_IS_OBJECT(obj))
1103 g_object_unref (obj);
1107 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1110 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1118 g_free (data->subject);
1119 g_free (data->plain_body);
1120 g_free (data->html_body);
1121 g_free (data->account_name);
1123 if (data->draft_msg != NULL) {
1124 g_object_unref (data->draft_msg);
1125 data->draft_msg = NULL;
1128 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1129 g_list_free (data->attachments);
1131 g_slice_free (MsgData, data);
1135 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1138 ModestMsgEditWindowPrivate *priv = NULL;
1139 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1141 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1143 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1145 return MODEST_MSG_EDIT_FORMAT_HTML;
1147 return MODEST_MSG_EDIT_FORMAT_TEXT;
1151 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1152 ModestMsgEditFormat format)
1154 ModestMsgEditWindowPrivate *priv;
1156 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1157 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1160 case MODEST_MSG_EDIT_FORMAT_HTML:
1161 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1163 case MODEST_MSG_EDIT_FORMAT_TEXT:
1164 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1167 g_return_if_reached ();
1171 ModestMsgEditFormatState *
1172 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1174 ModestMsgEditFormatState *format_state = NULL;
1175 ModestMsgEditWindowPrivate *priv;
1176 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1178 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1179 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1181 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1183 format_state = g_new0 (ModestMsgEditFormatState, 1);
1184 format_state->bold = buffer_format->bold&0x1;
1185 format_state->italics = buffer_format->italic&0x1;
1186 format_state->bullet = buffer_format->bullet&0x1;
1187 format_state->color = buffer_format->color;
1188 format_state->font_size = buffer_format->font_size;
1189 format_state->font_family = wp_get_font_name (buffer_format->font);
1190 format_state->justification = buffer_format->justification;
1191 g_free (buffer_format);
1193 return format_state;
1198 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1199 const ModestMsgEditFormatState *format_state)
1201 ModestMsgEditWindowPrivate *priv;
1202 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1203 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1204 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1205 g_return_if_fail (format_state != NULL);
1207 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1208 gtk_widget_grab_focus (priv->msg_body);
1209 buffer_format->bold = (format_state->bold != FALSE);
1210 buffer_format->italic = (format_state->italics != FALSE);
1211 buffer_format->color = format_state->color;
1212 buffer_format->font_size = format_state->font_size;
1213 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1214 buffer_format->justification = format_state->justification;
1215 buffer_format->bullet = format_state->bullet;
1217 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1219 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1220 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1221 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1222 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1223 buffer_format->cs.font = (buffer_format->font != current_format->font);
1224 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1225 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1227 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1228 if (buffer_format->cs.bold) {
1229 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1231 if (buffer_format->cs.italic) {
1232 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1234 if (buffer_format->cs.color) {
1235 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1237 if (buffer_format->cs.font_size) {
1238 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, (gpointer) (buffer_format->font_size));
1240 if (buffer_format->cs.justification) {
1241 switch (buffer_format->justification) {
1242 case GTK_JUSTIFY_LEFT:
1243 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1245 case GTK_JUSTIFY_CENTER:
1246 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1248 case GTK_JUSTIFY_RIGHT:
1249 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1256 if (buffer_format->cs.font) {
1257 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, (gpointer) (buffer_format->font));
1259 if (buffer_format->cs.bullet) {
1260 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1262 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1263 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1265 g_free (current_format);
1270 toggle_action_set_active_block_notify (GtkToggleAction *action,
1273 GSList *proxies = NULL;
1275 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1276 proxies != NULL; proxies = g_slist_next (proxies)) {
1277 GtkWidget *widget = (GtkWidget *) proxies->data;
1278 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1281 gtk_toggle_action_set_active (action, value);
1283 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1284 proxies != NULL; proxies = g_slist_next (proxies)) {
1285 GtkWidget *widget = (GtkWidget *) proxies->data;
1286 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1291 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1293 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1295 ModestWindowPrivate *parent_priv;
1296 ModestMsgEditWindowPrivate *priv;
1297 GtkWidget *new_size_menuitem;
1298 GtkWidget *new_font_menuitem;
1300 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1301 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1303 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1304 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1305 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1306 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1308 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1309 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1310 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1313 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1315 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1316 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1318 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1319 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1321 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1322 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1324 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1325 G_CALLBACK (modest_msg_edit_window_color_button_change),
1327 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1328 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1329 G_CALLBACK (modest_msg_edit_window_color_button_change),
1332 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1333 buffer_format->font_size))->data);
1334 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1338 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1339 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1340 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1342 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1343 G_CALLBACK (modest_msg_edit_window_size_change),
1345 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1346 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1347 G_CALLBACK (modest_msg_edit_window_size_change),
1351 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1352 buffer_format->font))->data);
1353 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1357 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1358 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1359 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1361 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1362 G_CALLBACK (modest_msg_edit_window_font_change),
1364 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1365 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1366 G_CALLBACK (modest_msg_edit_window_font_change),
1370 g_free (buffer_format);
1376 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1379 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1380 ModestMsgEditWindowPrivate *priv;
1381 GtkWidget *dialog = NULL;
1383 const GdkColor *new_color = NULL;
1385 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1386 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1388 #ifdef MODEST_HILDON_VERSION_0
1389 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1390 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1392 dialog = hildon_color_chooser_new ();
1393 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1394 #endif /*MODEST_HILDON_VERSION_0*/
1395 g_free (buffer_format);
1397 response = gtk_dialog_run (GTK_DIALOG (dialog));
1399 case GTK_RESPONSE_OK: {
1400 #ifdef MODEST_HILDON_VERSION_0
1401 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1404 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1406 #endif /*MODEST_HILDON_VERSION_0*/
1413 gtk_widget_destroy (dialog);
1415 if (new_color != NULL)
1416 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1421 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1424 ModestMsgEditWindowPrivate *priv;
1425 GtkWidget *dialog = NULL;
1427 GdkColor *old_color = NULL;
1428 const GdkColor *new_color = NULL;
1430 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1431 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1433 #ifdef MODEST_HILDON_VERSION_0
1434 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1435 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1437 dialog = hildon_color_chooser_new ();
1438 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1439 #endif /*MODEST_HILDON_VERSION_9*/
1441 response = gtk_dialog_run (GTK_DIALOG (dialog));
1443 case GTK_RESPONSE_OK: {
1444 #ifdef MODEST_HILDON_VERSION_0
1445 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1448 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1450 #endif /*MODEST_HILDON_VERSION_0*/
1456 gtk_widget_destroy (dialog);
1458 if (new_color != NULL)
1459 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1465 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1468 ModestMsgEditWindowPrivate *priv;
1469 GtkWidget *dialog = NULL;
1471 GSList *uris = NULL;
1472 GSList *uri_node = NULL;
1474 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1476 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1477 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1478 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1480 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1482 response = gtk_dialog_run (GTK_DIALOG (dialog));
1484 case GTK_RESPONSE_OK:
1485 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1490 gtk_widget_destroy (dialog);
1492 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1494 GnomeVFSHandle *handle = NULL;
1495 GnomeVFSResult result;
1496 GtkTextIter position;
1497 GtkTextMark *insert_mark;
1499 uri = (const gchar *) uri_node->data;
1500 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1501 if (result == GNOME_VFS_OK) {
1502 GdkPixbufLoader *loader;
1504 GnomeVFSFileInfo info;
1505 gchar *filename, *basename, *escaped_filename;
1506 TnyMimePart *mime_part;
1509 const gchar *mime_type = NULL;
1510 GnomeVFSURI *vfs_uri;
1512 vfs_uri = gnome_vfs_uri_new (uri);
1514 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
1515 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
1516 g_free (escaped_filename);
1517 gnome_vfs_uri_unref (vfs_uri);
1519 if (gnome_vfs_get_file_info (uri, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
1520 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
1522 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1524 mime_part = tny_platform_factory_new_mime_part
1525 (modest_runtime_get_platform_factory ());
1526 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1528 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1530 content_id = g_strdup_printf ("%d", priv->last_cid);
1531 tny_mime_part_set_content_id (mime_part, content_id);
1532 g_free (content_id);
1535 basename = g_path_get_basename (filename);
1536 tny_mime_part_set_filename (mime_part, basename);
1539 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1540 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1542 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1543 gtk_widget_show_all (priv->attachments_caption);
1544 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1547 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1548 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1549 unsigned char read_buffer[128];
1551 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1552 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1555 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1556 g_object_ref (pixbuf);
1557 gdk_pixbuf_loader_close (loader, NULL);
1558 g_object_unref (loader);
1560 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1561 GdkPixbuf *new_pixbuf;
1563 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1564 gdk_pixbuf_get_width (pixbuf);
1565 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1566 g_object_unref (pixbuf);
1567 pixbuf = new_pixbuf;
1570 if (pixbuf != NULL) {
1571 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1572 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1573 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1582 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1585 ModestMsgEditWindowPrivate *priv;
1586 GtkWidget *dialog = NULL;
1588 GSList *uris = NULL;
1591 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1593 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1594 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
1595 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1597 response = gtk_dialog_run (GTK_DIALOG (dialog));
1599 case GTK_RESPONSE_OK:
1600 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1605 gtk_widget_destroy (dialog);
1607 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1609 GnomeVFSHandle *handle = NULL;
1610 GnomeVFSResult result;
1612 uri = (const gchar *) uri_node->data;
1613 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1614 if (result == GNOME_VFS_OK) {
1615 TnyMimePart *mime_part;
1617 const gchar *mime_type = NULL;
1619 gchar *escaped_filename;
1622 GnomeVFSFileInfo info;
1623 GnomeVFSURI *vfs_uri;
1625 vfs_uri = gnome_vfs_uri_new (uri);
1628 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
1629 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
1630 g_free (escaped_filename);
1631 gnome_vfs_uri_unref (vfs_uri);
1633 if (gnome_vfs_get_file_info (uri,
1635 GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
1636 GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
1638 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1639 mime_part = tny_platform_factory_new_mime_part
1640 (modest_runtime_get_platform_factory ());
1641 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1643 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1645 content_id = g_strdup_printf ("%d", priv->last_cid);
1646 tny_mime_part_set_content_id (mime_part, content_id);
1647 g_free (content_id);
1650 basename = g_path_get_basename (filename);
1651 tny_mime_part_set_filename (mime_part, basename);
1654 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1655 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1657 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1658 gtk_widget_show_all (priv->attachments_caption);
1659 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1664 g_slist_foreach (uris, (GFunc) g_free, NULL);
1665 g_slist_free (uris);
1669 modest_msg_edit_window_attach_file_noninteractive (
1670 ModestMsgEditWindow *window,
1671 const gchar *file_uri)
1674 ModestMsgEditWindowPrivate *priv;
1676 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1678 if (file_uri && strlen(file_uri)) {
1681 /* TODO: We should probably try to use only the URI,
1682 * instead of using a filename.
1684 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1686 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1689 file_id = g_open (filename, O_RDONLY, 0);
1690 if (file_id != -1) {
1691 TnyMimePart *mime_part;
1693 const gchar *mime_type;
1696 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1697 mime_type = gnome_vfs_get_mime_type(filename);
1699 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1701 mime_part = tny_platform_factory_new_mime_part
1702 (modest_runtime_get_platform_factory ());
1703 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1705 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1707 content_id = g_strdup_printf ("%d", priv->last_cid);
1708 tny_mime_part_set_content_id (mime_part, content_id);
1709 g_free (content_id);
1712 basename = g_path_get_basename (filename);
1713 tny_mime_part_set_filename (mime_part, basename);
1716 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1717 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1719 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1720 gtk_widget_show_all (priv->attachments_caption);
1721 } else if (file_id == -1) {
1723 g_warning("file to be attached does not exist: %s", filename);
1731 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1734 ModestMsgEditWindowPrivate *priv;
1735 gboolean clean_list = FALSE;
1737 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1738 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1740 if (att_list == NULL) {
1741 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1745 if (att_list == NULL) {
1746 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1748 GtkWidget *confirmation_dialog = NULL;
1749 gboolean dialog_response;
1751 gchar *message = NULL;
1752 const gchar *filename = NULL;
1754 if (att_list->next == NULL) {
1755 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1759 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1760 att_list->next == NULL), filename);
1761 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1763 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1764 gtk_widget_destroy (confirmation_dialog);
1765 if (!dialog_response) {
1767 g_list_free (att_list);
1770 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1772 for (node = att_list; node != NULL; node = g_list_next (node)) {
1773 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1774 const gchar *att_id;
1775 priv->attachments = g_list_remove (priv->attachments, mime_part);
1777 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1779 if (priv->attachments == NULL)
1780 gtk_widget_hide (priv->attachments_caption);
1781 att_id = tny_mime_part_get_content_id (mime_part);
1783 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1785 g_object_unref (mime_part);
1786 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1791 g_list_free (att_list);
1795 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1798 ModestMsgEditWindowPrivate *priv;
1799 GdkColor *new_color;
1800 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1802 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1803 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1806 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1808 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1810 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1812 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1817 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1820 ModestMsgEditWindowPrivate *priv;
1821 gint new_size_index;
1822 ModestMsgEditWindow *window;
1825 window = MODEST_MSG_EDIT_WINDOW (userdata);
1826 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1827 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1829 if (gtk_check_menu_item_get_active (menu_item)) {
1831 WPTextBufferFormat format;
1833 memset (&format, 0, sizeof (format));
1834 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
1836 label = gtk_bin_get_child (GTK_BIN (menu_item));
1838 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1839 format.cs.font_size = TRUE;
1840 format.cs.text_position = TRUE;
1841 format.cs.font = TRUE;
1842 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1843 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
1845 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1846 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1847 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1849 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1850 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1851 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1857 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1860 ModestMsgEditWindowPrivate *priv;
1861 gint new_font_index;
1862 ModestMsgEditWindow *window;
1865 window = MODEST_MSG_EDIT_WINDOW (userdata);
1866 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1867 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1869 if (gtk_check_menu_item_get_active (menu_item)) {
1872 label = gtk_bin_get_child (GTK_BIN (menu_item));
1874 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1876 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1877 (gpointer) new_font_index))
1878 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1880 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1881 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1882 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1888 modest_msg_edit_window_set_zoom (ModestWindow *window,
1891 ModestMsgEditWindowPrivate *priv;
1892 ModestWindowPrivate *parent_priv;
1893 GtkRadioAction *zoom_radio_action;
1895 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1897 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1898 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1899 priv->zoom_level = zoom;
1900 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom*DEFAULT_FONT_SCALE);
1902 /* Zoom level menu options should be updated with the current zoom level */
1903 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1904 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1905 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1906 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1907 /* FIXME: Not availible before Gtk 2.10 */
1909 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1914 modest_msg_edit_window_get_zoom (ModestWindow *window)
1916 ModestMsgEditWindowPrivate *priv;
1918 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1920 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1921 return priv->zoom_level;
1925 zoom_allowed (ModestMsgEditWindow *window)
1929 focus = gtk_window_get_focus (GTK_WINDOW (window));
1930 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1934 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1936 ModestWindowPrivate *parent_priv;
1937 GtkRadioAction *zoom_radio_action;
1938 GSList *group, *node;
1940 /* First we check if the text view is focused. If not, zooming is not allowed */
1941 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1942 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1946 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1947 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1948 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1950 group = gtk_radio_action_get_group (zoom_radio_action);
1952 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1953 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1957 for (node = group; node != NULL; node = g_slist_next (node)) {
1958 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1959 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1967 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1969 ModestWindowPrivate *parent_priv;
1970 GtkRadioAction *zoom_radio_action;
1971 GSList *group, *node;
1973 /* First we check if the text view is focused. If not, zooming is not allowed */
1974 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1975 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1979 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1980 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1981 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1983 group = gtk_radio_action_get_group (zoom_radio_action);
1985 for (node = group; node != NULL; node = g_slist_next (node)) {
1986 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1987 if (node->next != NULL) {
1988 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1991 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1999 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
2001 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
2002 ModestWindowPrivate *parent_priv;
2003 ModestWindowMgr *mgr;
2004 gboolean is_fullscreen;
2005 GtkAction *fs_toggle_action;
2008 mgr = modest_runtime_get_window_mgr ();
2009 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
2011 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
2013 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2014 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2015 if (is_fullscreen != active)
2016 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2024 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
2026 ModestWindowPrivate *parent_priv;
2027 GtkAction *fs_toggle_action;
2030 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2032 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2033 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
2034 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
2038 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2041 ModestMsgEditWindowPrivate *priv = NULL;
2042 const gchar *recipients;
2043 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2045 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2046 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2047 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
2048 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2049 gtk_widget_show (priv->cc_caption);
2051 gtk_widget_hide (priv->cc_caption);
2052 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2056 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2059 ModestMsgEditWindowPrivate *priv = NULL;
2060 const gchar *recipients;
2061 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2063 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2064 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2065 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2066 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2067 gtk_widget_show (priv->bcc_caption);
2069 gtk_widget_hide (priv->bcc_caption);
2070 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2074 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2075 ModestRecptEditor *editor)
2077 ModestMsgEditWindowPrivate *priv;
2079 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2080 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2081 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2083 if (editor == NULL) {
2084 GtkWidget *view_focus;
2085 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2087 /* This code should be kept in sync with ModestRecptEditor. The
2088 textview inside the recpt editor is the one that really gets the
2089 focus. As it's inside a scrolled window, and this one inside the
2090 hbox recpt editor inherits from, we'll need to go up in the
2091 hierarchy to know if the text view is part of the recpt editor
2092 or if it's a different text entry */
2094 if (gtk_widget_get_parent (view_focus)) {
2095 GtkWidget *first_parent;
2097 first_parent = gtk_widget_get_parent (view_focus);
2098 if (gtk_widget_get_parent (first_parent) &&
2099 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2100 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2105 editor = MODEST_RECPT_EDITOR (priv->to_field);
2109 modest_address_book_select_addresses (editor);
2114 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2116 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2118 modest_msg_edit_window_open_addressbook (window, NULL);
2122 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2123 gboolean show_toolbar)
2125 ModestWindowPrivate *parent_priv;
2127 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2128 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2130 /* FIXME: we can not just use the code of
2131 modest_msg_edit_window_setup_toolbar because it has a
2132 mixture of both initialization and creation code. */
2135 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2137 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2141 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2142 TnyHeaderFlags priority_flags)
2144 ModestMsgEditWindowPrivate *priv;
2145 ModestWindowPrivate *parent_priv;
2147 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2149 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2150 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2151 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2153 if (priv->priority_flags != priority_flags) {
2154 GtkAction *priority_action = NULL;
2156 priv->priority_flags = priority_flags;
2158 switch (priority_flags) {
2159 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2160 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2161 gtk_widget_show (priv->priority_icon);
2162 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2163 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2165 case TNY_HEADER_FLAG_LOW_PRIORITY:
2166 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2167 gtk_widget_show (priv->priority_icon);
2168 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2169 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2172 gtk_widget_hide (priv->priority_icon);
2173 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2174 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2177 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2178 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2183 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2186 ModestMsgEditWindowPrivate *priv;
2187 ModestWindowPrivate *parent_priv;
2188 gint current_format;
2190 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2192 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2193 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2195 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2196 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2198 if (current_format != file_format) {
2199 switch (file_format) {
2200 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2201 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2203 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2207 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2208 response = gtk_dialog_run (GTK_DIALOG (dialog));
2209 gtk_widget_destroy (dialog);
2210 if (response == GTK_RESPONSE_OK) {
2211 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2213 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2214 toggle_action_set_active_block_notify (action, TRUE);
2219 update_dimmed (window);
2224 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2227 ModestMsgEditWindowPrivate *priv;
2228 WPTextBufferFormat oldfmt, fmt;
2229 gint old_position = 0;
2233 GdkColor *color = NULL;
2234 gboolean bold, bold_set, italic, italic_set;
2235 gboolean underline, underline_set;
2236 gboolean strikethrough, strikethrough_set;
2237 gboolean position_set;
2238 gboolean font_size_set, font_set, color_set;
2241 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2242 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2244 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2246 /* First we get the currently selected font information */
2247 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2248 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2250 switch (oldfmt.text_position) {
2251 case TEXT_POSITION_NORMAL:
2254 case TEXT_POSITION_SUPERSCRIPT:
2262 g_object_set (G_OBJECT (dialog),
2263 "bold", oldfmt.bold != FALSE,
2264 "bold-set", !oldfmt.cs.bold,
2265 "underline", oldfmt.underline != FALSE,
2266 "underline-set", !oldfmt.cs.underline,
2267 "italic", oldfmt.italic != FALSE,
2268 "italic-set", !oldfmt.cs.italic,
2269 "strikethrough", oldfmt.strikethrough != FALSE,
2270 "strikethrough-set", !oldfmt.cs.strikethrough,
2271 "color", &oldfmt.color,
2272 "color-set", !oldfmt.cs.color,
2273 "size", wp_font_size[oldfmt.font_size],
2274 "size-set", !oldfmt.cs.font_size,
2275 "position", old_position,
2276 "position-set", !oldfmt.cs.text_position,
2277 "family", wp_get_font_name (oldfmt.font),
2278 "family-set", !oldfmt.cs.font,
2281 gtk_widget_show_all (dialog);
2282 response = gtk_dialog_run (GTK_DIALOG (dialog));
2283 if (response == GTK_RESPONSE_OK) {
2285 g_object_get( dialog,
2287 "bold-set", &bold_set,
2288 "underline", &underline,
2289 "underline-set", &underline_set,
2291 "italic-set", &italic_set,
2292 "strikethrough", &strikethrough,
2293 "strikethrough-set", &strikethrough_set,
2295 "color-set", &color_set,
2297 "size-set", &font_size_set,
2298 "family", &font_name,
2299 "family-set", &font_set,
2300 "position", &position,
2301 "position-set", &position_set,
2306 if (response == GTK_RESPONSE_OK) {
2307 memset(&fmt, 0, sizeof(fmt));
2313 fmt.italic = italic;
2314 fmt.cs.italic = TRUE;
2316 if (underline_set) {
2317 fmt.underline = underline;
2318 fmt.cs.underline = TRUE;
2320 if (strikethrough_set) {
2321 fmt.strikethrough = strikethrough;
2322 fmt.cs.strikethrough = TRUE;
2327 ? TEXT_POSITION_NORMAL
2328 : ( ( position == 1 )
2329 ? TEXT_POSITION_SUPERSCRIPT
2330 : TEXT_POSITION_SUBSCRIPT );
2331 fmt.cs.text_position = TRUE;
2335 fmt.cs.color = TRUE;
2338 fmt.font = wp_get_font_index(font_name,
2343 if (font_size_set) {
2344 fmt.font_size = wp_get_font_size_index(
2345 font_size, DEFAULT_FONT_SIZE);
2346 fmt.cs.font_size = TRUE;
2348 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2350 gtk_widget_destroy (dialog);
2352 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2356 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2358 ModestMsgEditWindowPrivate *priv;
2360 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2361 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2363 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2365 update_dimmed (window);
2370 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2372 ModestMsgEditWindowPrivate *priv;
2374 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2375 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2377 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2379 update_dimmed (window);
2384 update_dimmed (ModestMsgEditWindow *window)
2386 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2387 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2391 gboolean editor_focused;
2393 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2394 editor_focused = gtk_widget_is_focus (priv->msg_body);
2396 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2397 gtk_action_set_sensitive (action, rich_text && editor_focused);
2398 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2399 gtk_action_set_sensitive (action, rich_text && editor_focused);
2400 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2401 gtk_action_set_sensitive (action, rich_text && editor_focused);
2402 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2403 gtk_action_set_sensitive (action, rich_text && editor_focused);
2404 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2405 gtk_action_set_sensitive (action, rich_text && editor_focused);
2406 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2407 gtk_action_set_sensitive (action, rich_text && editor_focused);
2408 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2409 gtk_action_set_sensitive (action, rich_text && editor_focused);
2410 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2411 gtk_action_set_sensitive (action, rich_text && editor_focused);
2412 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2413 gtk_action_set_sensitive (action, rich_text && editor_focused);
2414 widget = priv->font_color_button;
2415 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2416 widget = priv->font_size_toolitem;
2417 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2418 widget = priv->font_face_toolitem;
2419 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2423 setup_insensitive_handlers (ModestMsgEditWindow *window)
2425 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2426 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2429 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2430 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2431 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2432 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2433 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2434 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2435 widget = priv->font_color_button;
2436 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2437 widget = priv->font_size_toolitem;
2438 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2439 widget = priv->font_face_toolitem;
2440 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2445 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2447 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2450 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2451 gtk_action_set_sensitive (action, can_undo);
2455 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2457 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2460 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu");
2461 gtk_action_set_sensitive (action, can_redo);
2465 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2468 GtkTextIter match_start, match_end;
2470 if (image_id == NULL)
2473 gtk_text_buffer_get_start_iter (buffer, &iter);
2475 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2476 GSList *tags = gtk_text_iter_get_tags (&match_start);
2478 for (node = tags; node != NULL; node = g_slist_next (node)) {
2479 GtkTextTag *tag = (GtkTextTag *) node->data;
2480 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2481 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2482 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2484 offset = gtk_text_iter_get_offset (&match_start);
2485 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2486 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2490 gtk_text_iter_forward_char (&iter);
2495 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2497 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2498 GtkTextIter real_start, real_end;
2499 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2501 if (gtk_text_iter_compare (start, end) > 0) {
2505 real_start = *start;
2509 GSList *tags = gtk_text_iter_get_tags (&real_start);
2511 for (node = tags; node != NULL; node = g_slist_next (node)) {
2512 GtkTextTag *tag = (GtkTextTag *) node->data;
2513 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2514 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2516 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2518 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2521 } while (gtk_text_iter_forward_char (&real_start)&&
2522 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2526 msg_body_focus (GtkWidget *focus,
2527 GdkEventFocus *event,
2531 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2536 recpt_field_changed (GtkTextBuffer *buffer,
2537 ModestMsgEditWindow *editor)
2539 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2540 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2541 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2542 gboolean dim = FALSE;
2545 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2546 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2547 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2549 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2550 gtk_text_buffer_get_char_count (cc_buffer) +
2551 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2553 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2554 gtk_action_set_sensitive (action, !dim);
2555 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2556 gtk_action_set_sensitive (action, !dim);
2560 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2562 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2566 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2568 gboolean rich_text, editor_focused;
2570 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2571 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2572 editor_focused = gtk_widget_is_focus (priv->msg_body);
2575 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2576 else if (!editor_focused)
2577 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2581 reset_modified (ModestMsgEditWindow *editor)
2583 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2584 GtkTextBuffer *buffer;
2586 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2587 gtk_text_buffer_set_modified (buffer, FALSE);
2588 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2589 gtk_text_buffer_set_modified (buffer, FALSE);
2590 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2591 gtk_text_buffer_set_modified (buffer, FALSE);
2592 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2596 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2598 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2599 GtkTextBuffer *buffer;
2601 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2602 if (gtk_text_buffer_get_modified (buffer))
2604 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2605 if (gtk_text_buffer_get_modified (buffer))
2607 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2608 if (gtk_text_buffer_get_modified (buffer))
2610 if (gtk_text_buffer_get_modified (priv->text_buffer))
2617 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2619 ModestMsgEditWindowPrivate *priv = NULL;
2621 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2622 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2624 /* check if there's no recipient added */
2625 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2626 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2627 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2628 /* no recipient contents, then select contacts */
2629 modest_msg_edit_window_open_addressbook (window, NULL);
2633 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2635 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2637 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2640 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2647 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2648 ModestMsgEditWindow *window)
2650 modest_msg_edit_window_attach_file (window);
2654 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2656 ModestMsgEditWindow *window)
2658 ModestWindowPrivate *parent_priv;
2659 ModestMsgEditWindowPrivate *priv;
2661 gboolean has_selection;
2663 GList *selected_attachments = NULL;
2664 gint n_att_selected = 0;
2666 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2667 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2668 has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL);
2669 focused = gtk_window_get_focus (GTK_WINDOW (window));
2671 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2672 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2673 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2674 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2676 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2677 n_att_selected = g_list_length (selected_attachments);
2678 g_list_free (selected_attachments);
2680 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2681 gtk_action_set_sensitive (action, n_att_selected == 1);
2683 update_paste_dimming (window);
2687 update_window_title (ModestMsgEditWindow *window)
2689 ModestMsgEditWindowPrivate *priv = NULL;
2690 const gchar *subject;
2692 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2693 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2694 if (subject == NULL || subject[0] == '\0')
2695 subject = _("mail_va_new_email");
2697 gtk_window_set_title (GTK_WINDOW (window), subject);
2702 subject_field_changed (GtkEditable *editable,
2703 ModestMsgEditWindow *window)
2705 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2706 update_window_title (window);
2707 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2711 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2714 ModestMsgEditWindowPrivate *priv = NULL;
2716 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2717 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2719 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2721 gtk_widget_show_all (priv->find_toolbar);
2722 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2724 gtk_widget_hide_all (priv->find_toolbar);
2725 gtk_widget_grab_focus (priv->msg_body);
2731 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2733 GtkTextIter *match_start,
2734 GtkTextIter *match_end)
2736 GtkTextIter end_iter;
2737 gchar *str_casefold;
2740 gchar *range_casefold;
2743 gboolean result = FALSE;
2750 gtk_text_iter_forward_to_end (&end_iter);
2752 str_casefold = g_utf8_casefold (str, -1);
2753 str_chars_n = strlen (str);
2755 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2756 range_casefold = g_utf8_casefold (range_text, -1);
2757 range_chars_n = strlen (range_casefold);
2759 if (range_chars_n < str_chars_n) {
2760 g_free (str_casefold);
2761 g_free (range_text);
2762 g_free (range_casefold);
2766 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2767 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2768 if (!g_utf8_collate (range_subtext, str_casefold)) {
2769 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2771 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2772 match_start, match_end, NULL);
2773 g_free (found_text);
2775 g_free (range_subtext);
2779 g_free (str_casefold);
2780 g_free (range_text);
2781 g_free (range_casefold);
2788 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2789 ModestMsgEditWindow *window)
2791 gchar *current_search = NULL;
2792 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2794 GtkTextIter selection_start, selection_end;
2795 GtkTextIter match_start, match_end;
2796 gboolean continue_search = FALSE;
2798 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2799 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2800 g_free (current_search);
2801 g_free (priv->last_search);
2802 priv->last_search = NULL;
2803 /* Information banner about empty search */
2804 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2808 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2809 continue_search = TRUE;
2811 g_free (priv->last_search);
2812 priv->last_search = g_strdup (current_search);
2815 if (continue_search) {
2816 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2817 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2818 &match_start, &match_end);
2820 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2822 GtkTextIter buffer_start;
2823 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2824 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2825 &match_start, &match_end);
2827 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2830 /* Mark as selected the string found in search */
2832 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2833 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2835 g_free (priv->last_search);
2836 priv->last_search = NULL;
2838 g_free (current_search);
2842 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2843 ModestMsgEditWindow *window)
2845 GtkToggleAction *toggle;
2846 ModestWindowPrivate *parent_priv;
2847 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2849 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2850 gtk_toggle_action_set_active (toggle, FALSE);
2855 update_paste_dimming (ModestMsgEditWindow *window)
2857 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2858 GtkAction *action = NULL;
2859 GtkClipboard *clipboard = NULL;
2863 focused = gtk_window_get_focus (GTK_WINDOW (window));
2865 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2866 active = gtk_clipboard_wait_is_text_available (clipboard);
2869 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2873 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2874 gtk_action_set_sensitive (action, active);
2879 update_select_all_dimming (ModestMsgEditWindow *window)
2882 gboolean dimmed = FALSE;
2884 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2886 focused = gtk_window_get_focus (GTK_WINDOW (window));
2887 if (GTK_IS_ENTRY (focused)) {
2888 const gchar *current_text;
2889 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2890 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2891 } else if (GTK_IS_TEXT_VIEW (focused)) {
2892 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2893 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2894 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2897 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2898 gtk_action_set_sensitive (action, !dimmed);
2902 update_zoom_dimming (ModestMsgEditWindow *window)
2905 gboolean dimmed = FALSE;
2907 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2909 focused = gtk_window_get_focus (GTK_WINDOW (window));
2910 dimmed = ! WP_IS_TEXT_VIEW (focused);
2911 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2912 gtk_action_set_sensitive (action, !dimmed);
2916 edit_menu_activated (GtkAction *action,
2919 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2921 update_select_all_dimming (window);
2922 update_paste_dimming (window);
2925 view_menu_activated (GtkAction *action,
2928 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2930 update_zoom_dimming (window);
2934 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2936 ModestMsgEditWindowPrivate *priv;
2938 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2943 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
2946 ModestMsgEditWindowPrivate *priv;
2948 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2954 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
2957 ModestMsgEditWindowPrivate *priv;
2958 TnyHeader *header = NULL;
2960 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2961 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
2963 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2964 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
2966 if (priv->draft_msg != NULL) {
2967 header = tny_msg_get_header (priv->draft_msg);
2968 if (TNY_IS_HEADER (header)) {
2969 modest_window_mgr_unregister_header (mgr, header);
2971 g_object_unref (priv->draft_msg);
2974 if (draft != NULL) {
2975 g_object_ref (draft);
2976 header = tny_msg_get_header (draft);
2977 if (TNY_IS_HEADER (header))
2978 modest_window_mgr_register_header (mgr, header);
2981 priv->draft_msg = draft;