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 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
434 gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
436 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
438 priv->find_toolbar = hildon_find_toolbar_new (NULL);
439 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
441 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
443 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
444 G_CALLBACK (text_buffer_refresh_attributes), obj);
445 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
446 G_CALLBACK (text_buffer_delete_range), obj);
447 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
448 G_CALLBACK (text_buffer_can_undo), obj);
449 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
450 G_CALLBACK (text_buffer_can_redo), obj);
451 g_signal_connect (G_OBJECT (obj), "window-state-event",
452 G_CALLBACK (modest_msg_edit_window_window_state_event),
454 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
455 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
456 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
457 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
458 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
459 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
461 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
462 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
464 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
465 G_CALLBACK (msg_body_focus), obj);
466 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
467 G_CALLBACK (msg_body_focus), obj);
468 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
469 "changed", G_CALLBACK (recpt_field_changed), obj);
470 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
471 "changed", G_CALLBACK (recpt_field_changed), obj);
472 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
473 "changed", G_CALLBACK (recpt_field_changed), obj);
474 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
475 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
477 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
478 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
480 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
481 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
482 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
483 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->scroll), TRUE);
485 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
487 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
488 frame = gtk_frame_new (NULL);
489 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
491 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
492 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
493 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
495 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
496 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
497 gtk_widget_hide (priv->cc_caption);
499 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
500 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
501 gtk_widget_hide (priv->bcc_caption);
504 window_box = gtk_vbox_new (FALSE, 0);
505 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
506 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
507 gtk_container_add (GTK_CONTAINER(obj), window_box);
508 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
509 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
512 TODO: scroll_area was never instantiated.
513 Stop building without warnings-as-errors. murrayc.
514 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
515 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
518 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
519 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
525 modest_msg_edit_window_finalize (GObject *obj)
527 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
529 if (priv->clipboard_change_handler_id > 0) {
530 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
531 priv->clipboard_change_handler_id = 0;
534 if (priv->draft_msg != NULL) {
535 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
536 if (TNY_IS_HEADER (header)) {
537 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
538 modest_window_mgr_unregister_header (mgr, header);
540 g_object_unref (priv->draft_msg);
541 priv->draft_msg = NULL;
544 /* This had to stay alive for as long as the combobox that used it: */
545 modest_pair_list_free (priv->from_field_protos);
547 G_OBJECT_CLASS(parent_class)->finalize (obj);
551 menubar_to_menu (GtkUIManager *ui_manager)
553 GtkWidget *main_menu;
557 /* Create new main menu */
558 main_menu = gtk_menu_new();
560 /* Get the menubar from the UI manager */
561 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
563 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
567 menu = GTK_WIDGET (iter->data);
568 gtk_widget_reparent(menu, main_menu);
570 iter = g_list_next (iter);
577 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
580 const gchar *to, *cc, *bcc, *subject;
582 ModestMsgEditWindowPrivate *priv;
584 TnyHeaderFlags priority_flags;
585 TnyFolder *msg_folder;
587 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
588 g_return_if_fail (TNY_IS_MSG (msg));
590 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
592 header = tny_msg_get_header (msg);
593 to = tny_header_get_to (header);
594 cc = tny_header_get_cc (header);
595 bcc = tny_header_get_bcc (header);
596 subject = tny_header_get_subject (header);
597 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
600 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
602 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
603 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
604 gtk_widget_show (priv->cc_caption);
605 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
606 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
607 gtk_widget_hide (priv->cc_caption);
610 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
611 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
612 gtk_widget_show (priv->bcc_caption);
613 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
614 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
615 gtk_widget_hide (priv->bcc_caption);
618 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
619 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
622 update_window_title (self);
624 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
625 body = modest_tny_msg_get_body (msg, TRUE);
627 if ((body == NULL)||(body[0] == '\0')) {
629 body = modest_text_utils_convert_to_html ("");
631 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
632 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
635 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
638 /* Get the default format required from configuration */
639 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
640 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
643 /* Set the default focus depending on having already a To: field or not */
644 if ((!to)||(*to == '\0')) {
645 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
647 gtk_widget_grab_focus (priv->msg_body);
650 /* TODO: lower priority, select in the From: combo to the
651 value that comes from msg <- not sure, should it be
654 /* Add attachments to the view */
655 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
656 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
657 if (priv->attachments == NULL) {
658 gtk_widget_hide (priv->attachments_caption);
660 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
661 gtk_widget_show_all (priv->attachments_caption);
664 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
665 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
667 reset_modified (self);
669 update_dimmed (self);
670 text_buffer_can_undo (priv->text_buffer, FALSE, self);
671 text_buffer_can_redo (priv->text_buffer, FALSE, self);
673 /* we should set a reference to the incoming message if it is a draft */
674 msg_folder = tny_msg_get_folder (msg);
676 if (modest_tny_folder_is_local_folder (msg_folder) &&
677 modest_tny_folder_get_local_folder_type (msg_folder) == TNY_FOLDER_TYPE_DRAFTS)
678 priv->draft_msg = g_object_ref(msg);
679 g_object_unref (msg_folder);
684 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
687 GList *item_children, *node;
688 GtkWidget *bin_child;
690 bin_child = gtk_bin_get_child (GTK_BIN(item));
692 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
694 for (node = item_children; node != NULL; node = g_list_next (node)) {
695 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
696 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
699 g_list_free (item_children);
703 menu_tool_button_dont_expand (GtkMenuToolButton *item)
706 GList *item_children, *node;
708 box = gtk_bin_get_child (GTK_BIN (item));
709 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
710 item_children = gtk_container_get_children (GTK_CONTAINER (box));
712 for (node = item_children; node != NULL; node = g_list_next (node)) {
713 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
714 if (GTK_IS_TOGGLE_BUTTON (node->data))
715 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
716 else if (GTK_IS_BUTTON (node->data))
717 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
719 g_list_free (item_children);
724 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
726 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
727 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
728 GtkWidget *placeholder;
729 GtkWidget *tool_item;
734 GtkWidget *sizes_menu;
735 GtkWidget *fonts_menu;
736 GSList *radio_group = NULL;
741 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
742 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
744 /* should we hide the toolbar? */
745 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
746 gtk_widget_hide (parent_priv->toolbar);
748 /* Font color placeholder */
749 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
750 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
753 tool_item = GTK_WIDGET (gtk_tool_item_new ());
754 priv->font_color_button = hildon_color_button_new ();
755 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
756 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
757 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
758 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
759 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
760 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
761 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
763 /* Font size and face placeholder */
764 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
765 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
767 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
768 priv->size_tool_button_label = gtk_label_new (NULL);
769 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
770 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
771 size_text,"</span>", NULL);
772 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
774 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
775 sizes_menu = gtk_menu_new ();
776 priv->size_items_group = NULL;
778 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
779 GtkWidget *size_menu_item;
781 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
782 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
783 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
784 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
785 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
786 gtk_widget_show (size_menu_item);
788 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
792 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
793 GtkWidget *item = (GtkWidget *) node->data;
794 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
798 priv->size_items_group = g_slist_reverse (priv->size_items_group);
799 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
800 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
801 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
802 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
803 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
804 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
805 priv->font_size_toolitem = tool_item;
808 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
809 priv->font_tool_button_label = gtk_label_new (NULL);
810 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
811 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
813 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
814 fonts_menu = gtk_menu_new ();
815 priv->font_items_group = NULL;
817 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
818 GtkWidget *font_menu_item;
819 GtkWidget *child_label;
821 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
822 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
823 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
824 wp_get_font_name (font_index), "</span>", NULL);
825 gtk_label_set_markup (GTK_LABEL (child_label), markup);
828 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
829 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
830 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
831 gtk_widget_show (font_menu_item);
833 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
836 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
837 GtkWidget *item = (GtkWidget *) node->data;
838 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
841 priv->font_items_group = g_slist_reverse (priv->font_items_group);
842 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
843 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
844 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
845 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
846 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
847 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
848 priv->font_face_toolitem = tool_item;
850 /* Set expand and homogeneous for remaining items */
851 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
852 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
853 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
854 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
855 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
856 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
857 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
858 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
859 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
867 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
870 ModestWindowPrivate *parent_priv;
871 ModestMsgEditWindowPrivate *priv;
872 GtkActionGroup *action_group;
873 GError *error = NULL;
874 GdkPixbuf *window_icon = NULL;
877 gboolean prefer_formatted;
879 ModestPair *account_pair = NULL;
881 g_return_val_if_fail (msg, NULL);
882 g_return_val_if_fail (account_name, NULL);
884 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
886 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
887 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
889 parent_priv->ui_manager = gtk_ui_manager_new();
890 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
891 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
893 /* Add common actions */
894 gtk_action_group_add_actions (action_group,
895 modest_msg_edit_action_entries,
896 G_N_ELEMENTS (modest_msg_edit_action_entries),
898 gtk_action_group_add_toggle_actions (action_group,
899 modest_msg_edit_toggle_action_entries,
900 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
902 gtk_action_group_add_radio_actions (action_group,
903 modest_msg_edit_alignment_radio_action_entries,
904 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
906 G_CALLBACK (modest_ui_actions_on_change_justify),
908 gtk_action_group_add_radio_actions (action_group,
909 modest_msg_edit_zoom_action_entries,
910 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
912 G_CALLBACK (modest_ui_actions_on_change_zoom),
914 gtk_action_group_add_radio_actions (action_group,
915 modest_msg_edit_priority_action_entries,
916 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
918 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
920 gtk_action_group_add_radio_actions (action_group,
921 modest_msg_edit_file_format_action_entries,
922 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
923 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
924 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
926 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
927 g_object_unref (action_group);
929 /* Load the UI definition */
930 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
933 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
934 g_clear_error (&error);
937 /* Add accelerators */
938 gtk_window_add_accel_group (GTK_WINDOW (obj),
939 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
942 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
943 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
946 init_window (MODEST_MSG_EDIT_WINDOW(obj));
948 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
950 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
952 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
954 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
956 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
957 if (account_pair != NULL)
958 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
960 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
962 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
964 /* Set window icon */
965 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
967 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
968 g_object_unref (window_icon);
971 /* Dim at start clipboard actions */
972 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
973 gtk_action_set_sensitive (action, FALSE);
974 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
975 gtk_action_set_sensitive (action, FALSE);
976 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
977 gtk_action_set_sensitive (action, FALSE);
979 /* Update select all */
980 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
981 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
982 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
983 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
984 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
986 /* set initial state of cc and bcc */
987 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
988 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
989 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
990 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
991 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
992 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
994 /* Setup the file format */
995 conf = modest_runtime_get_conf ();
996 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
998 g_clear_error (&error);
999 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
1001 file_format = (prefer_formatted) ?
1002 MODEST_FILE_FORMAT_FORMATTED_TEXT :
1003 MODEST_FILE_FORMAT_PLAIN_TEXT;
1004 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
1006 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
1008 return (ModestWindow*) obj;
1012 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1014 GString **string_buffer = (GString **) user_data;
1016 *string_buffer = g_string_append (*string_buffer, buffer);
1022 * @result: A new string which should be freed with g_free().
1025 get_formatted_data (ModestMsgEditWindow *edit_window)
1027 ModestMsgEditWindowPrivate *priv;
1028 GString *string_buffer = g_string_new ("");
1030 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1032 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1034 return g_string_free (string_buffer, FALSE);
1039 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1042 const gchar *account_name;
1043 ModestMsgEditWindowPrivate *priv;
1045 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1047 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1049 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1050 g_return_val_if_fail (account_name, NULL);
1053 /* don't free these (except from) */
1054 data = g_slice_new0 (MsgData);
1055 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1057 data->account_name = g_strdup (account_name);
1058 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1059 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1060 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1061 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1062 if (priv->draft_msg) {
1063 data->draft_msg = g_object_ref (priv->draft_msg);
1065 data->draft_msg = NULL;
1068 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1070 gtk_text_buffer_get_bounds (buf, &b, &e);
1071 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1073 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1074 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1076 data->html_body = NULL;
1078 /* deep-copy the data */
1079 GList *cursor = priv->attachments;
1080 data->attachments = NULL;
1082 if (!(TNY_IS_MIME_PART(cursor->data))) {
1083 g_warning ("strange data in attachment list");
1086 data->attachments = g_list_append (data->attachments,
1087 g_object_ref (cursor->data));
1088 cursor = g_list_next (cursor);
1091 data->priority_flags = priv->priority_flags;
1098 unref_gobject (GObject *obj, gpointer data)
1100 if (!G_IS_OBJECT(obj))
1102 g_object_unref (obj);
1106 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1109 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1117 g_free (data->subject);
1118 g_free (data->plain_body);
1119 g_free (data->html_body);
1120 g_free (data->account_name);
1122 if (data->draft_msg != NULL) {
1123 g_object_unref (data->draft_msg);
1124 data->draft_msg = NULL;
1127 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1128 g_list_free (data->attachments);
1130 g_slice_free (MsgData, data);
1134 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1137 ModestMsgEditWindowPrivate *priv = NULL;
1138 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1140 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1142 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1144 return MODEST_MSG_EDIT_FORMAT_HTML;
1146 return MODEST_MSG_EDIT_FORMAT_TEXT;
1150 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1151 ModestMsgEditFormat format)
1153 ModestMsgEditWindowPrivate *priv;
1155 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1156 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1159 case MODEST_MSG_EDIT_FORMAT_HTML:
1160 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1162 case MODEST_MSG_EDIT_FORMAT_TEXT:
1163 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1166 g_return_if_reached ();
1170 ModestMsgEditFormatState *
1171 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1173 ModestMsgEditFormatState *format_state = NULL;
1174 ModestMsgEditWindowPrivate *priv;
1175 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1177 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1178 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1180 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1182 format_state = g_new0 (ModestMsgEditFormatState, 1);
1183 format_state->bold = buffer_format->bold&0x1;
1184 format_state->italics = buffer_format->italic&0x1;
1185 format_state->bullet = buffer_format->bullet&0x1;
1186 format_state->color = buffer_format->color;
1187 format_state->font_size = buffer_format->font_size;
1188 format_state->font_family = wp_get_font_name (buffer_format->font);
1189 format_state->justification = buffer_format->justification;
1190 g_free (buffer_format);
1192 return format_state;
1197 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1198 const ModestMsgEditFormatState *format_state)
1200 ModestMsgEditWindowPrivate *priv;
1201 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1202 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1203 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1204 g_return_if_fail (format_state != NULL);
1206 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1207 gtk_widget_grab_focus (priv->msg_body);
1208 buffer_format->bold = (format_state->bold != FALSE);
1209 buffer_format->italic = (format_state->italics != FALSE);
1210 buffer_format->color = format_state->color;
1211 buffer_format->font_size = format_state->font_size;
1212 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1213 buffer_format->justification = format_state->justification;
1214 buffer_format->bullet = format_state->bullet;
1216 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1218 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1219 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1220 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1221 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1222 buffer_format->cs.font = (buffer_format->font != current_format->font);
1223 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1224 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1226 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1227 if (buffer_format->cs.bold) {
1228 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1230 if (buffer_format->cs.italic) {
1231 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1233 if (buffer_format->cs.color) {
1234 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1236 if (buffer_format->cs.font_size) {
1237 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, (gpointer) (buffer_format->font_size));
1239 if (buffer_format->cs.justification) {
1240 switch (buffer_format->justification) {
1241 case GTK_JUSTIFY_LEFT:
1242 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1244 case GTK_JUSTIFY_CENTER:
1245 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1247 case GTK_JUSTIFY_RIGHT:
1248 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1255 if (buffer_format->cs.font) {
1256 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, (gpointer) (buffer_format->font));
1258 if (buffer_format->cs.bullet) {
1259 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1261 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1262 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1264 g_free (current_format);
1269 toggle_action_set_active_block_notify (GtkToggleAction *action,
1272 GSList *proxies = NULL;
1274 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1275 proxies != NULL; proxies = g_slist_next (proxies)) {
1276 GtkWidget *widget = (GtkWidget *) proxies->data;
1277 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1280 gtk_toggle_action_set_active (action, value);
1282 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1283 proxies != NULL; proxies = g_slist_next (proxies)) {
1284 GtkWidget *widget = (GtkWidget *) proxies->data;
1285 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1290 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1292 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1294 ModestWindowPrivate *parent_priv;
1295 ModestMsgEditWindowPrivate *priv;
1296 GtkWidget *new_size_menuitem;
1297 GtkWidget *new_font_menuitem;
1299 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1300 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1302 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1303 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1304 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1305 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1307 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1308 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1309 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1312 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1314 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1315 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1317 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1318 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1320 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1321 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1323 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1324 G_CALLBACK (modest_msg_edit_window_color_button_change),
1326 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1327 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1328 G_CALLBACK (modest_msg_edit_window_color_button_change),
1331 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1332 buffer_format->font_size))->data);
1333 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1337 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1338 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1339 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1341 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1342 G_CALLBACK (modest_msg_edit_window_size_change),
1344 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1345 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1346 G_CALLBACK (modest_msg_edit_window_size_change),
1350 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1351 buffer_format->font))->data);
1352 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1356 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1357 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1358 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1360 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1361 G_CALLBACK (modest_msg_edit_window_font_change),
1363 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1364 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1365 G_CALLBACK (modest_msg_edit_window_font_change),
1369 g_free (buffer_format);
1375 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1378 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1379 ModestMsgEditWindowPrivate *priv;
1380 GtkWidget *dialog = NULL;
1382 const GdkColor *new_color = NULL;
1384 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1385 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1387 #ifdef MODEST_HILDON_VERSION_0
1388 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1389 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1391 dialog = hildon_color_chooser_new ();
1392 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1393 #endif /*MODEST_HILDON_VERSION_0*/
1394 g_free (buffer_format);
1396 response = gtk_dialog_run (GTK_DIALOG (dialog));
1398 case GTK_RESPONSE_OK: {
1399 #ifdef MODEST_HILDON_VERSION_0
1400 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1403 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1405 #endif /*MODEST_HILDON_VERSION_0*/
1412 gtk_widget_destroy (dialog);
1414 if (new_color != NULL)
1415 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1420 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1423 ModestMsgEditWindowPrivate *priv;
1424 GtkWidget *dialog = NULL;
1426 GdkColor *old_color = NULL;
1427 const GdkColor *new_color = NULL;
1429 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1430 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1432 #ifdef MODEST_HILDON_VERSION_0
1433 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1434 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1436 dialog = hildon_color_chooser_new ();
1437 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1438 #endif /*MODEST_HILDON_VERSION_9*/
1440 response = gtk_dialog_run (GTK_DIALOG (dialog));
1442 case GTK_RESPONSE_OK: {
1443 #ifdef MODEST_HILDON_VERSION_0
1444 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1447 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1449 #endif /*MODEST_HILDON_VERSION_0*/
1455 gtk_widget_destroy (dialog);
1457 if (new_color != NULL)
1458 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1464 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1467 ModestMsgEditWindowPrivate *priv;
1468 GtkWidget *dialog = NULL;
1470 GSList *uris = NULL;
1471 GSList *uri_node = NULL;
1473 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1475 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1476 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1477 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1479 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1481 response = gtk_dialog_run (GTK_DIALOG (dialog));
1483 case GTK_RESPONSE_OK:
1484 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1489 gtk_widget_destroy (dialog);
1491 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1493 GnomeVFSHandle *handle = NULL;
1494 GnomeVFSResult result;
1495 GtkTextIter position;
1496 GtkTextMark *insert_mark;
1498 uri = (const gchar *) uri_node->data;
1499 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1500 if (result == GNOME_VFS_OK) {
1501 GdkPixbufLoader *loader;
1503 GnomeVFSFileInfo info;
1504 gchar *filename, *basename, *escaped_filename;
1505 TnyMimePart *mime_part;
1508 const gchar *mime_type = NULL;
1509 GnomeVFSURI *vfs_uri;
1511 vfs_uri = gnome_vfs_uri_new (uri);
1513 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
1514 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
1515 g_free (escaped_filename);
1516 gnome_vfs_uri_unref (vfs_uri);
1518 if (gnome_vfs_get_file_info (uri, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
1519 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
1521 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1523 mime_part = tny_platform_factory_new_mime_part
1524 (modest_runtime_get_platform_factory ());
1525 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1527 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1529 content_id = g_strdup_printf ("%d", priv->last_cid);
1530 tny_mime_part_set_content_id (mime_part, content_id);
1531 g_free (content_id);
1534 basename = g_path_get_basename (filename);
1535 tny_mime_part_set_filename (mime_part, basename);
1538 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1539 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1541 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1542 gtk_widget_show_all (priv->attachments_caption);
1543 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1546 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1547 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1548 unsigned char read_buffer[128];
1550 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1551 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1554 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1555 g_object_ref (pixbuf);
1556 gdk_pixbuf_loader_close (loader, NULL);
1557 g_object_unref (loader);
1559 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1560 GdkPixbuf *new_pixbuf;
1562 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1563 gdk_pixbuf_get_width (pixbuf);
1564 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1565 g_object_unref (pixbuf);
1566 pixbuf = new_pixbuf;
1569 if (pixbuf != NULL) {
1570 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1571 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1572 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1581 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1584 ModestMsgEditWindowPrivate *priv;
1585 GtkWidget *dialog = NULL;
1587 GSList *uris = NULL;
1590 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1592 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1593 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
1594 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1596 response = gtk_dialog_run (GTK_DIALOG (dialog));
1598 case GTK_RESPONSE_OK:
1599 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1604 gtk_widget_destroy (dialog);
1606 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1608 GnomeVFSHandle *handle = NULL;
1609 GnomeVFSResult result;
1611 uri = (const gchar *) uri_node->data;
1612 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1613 if (result == GNOME_VFS_OK) {
1614 TnyMimePart *mime_part;
1616 const gchar *mime_type = NULL;
1618 gchar *escaped_filename;
1621 GnomeVFSFileInfo info;
1622 GnomeVFSURI *vfs_uri;
1624 vfs_uri = gnome_vfs_uri_new (uri);
1627 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
1628 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
1629 g_free (escaped_filename);
1630 gnome_vfs_uri_unref (vfs_uri);
1632 if (gnome_vfs_get_file_info (uri,
1634 GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
1635 GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
1637 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1638 mime_part = tny_platform_factory_new_mime_part
1639 (modest_runtime_get_platform_factory ());
1640 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1642 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1644 content_id = g_strdup_printf ("%d", priv->last_cid);
1645 tny_mime_part_set_content_id (mime_part, content_id);
1646 g_free (content_id);
1649 basename = g_path_get_basename (filename);
1650 tny_mime_part_set_filename (mime_part, basename);
1653 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1654 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1656 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1657 gtk_widget_show_all (priv->attachments_caption);
1658 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1663 g_slist_foreach (uris, (GFunc) g_free, NULL);
1664 g_slist_free (uris);
1668 modest_msg_edit_window_attach_file_noninteractive (
1669 ModestMsgEditWindow *window,
1670 const gchar *file_uri)
1673 ModestMsgEditWindowPrivate *priv;
1675 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1677 if (file_uri && strlen(file_uri)) {
1680 /* TODO: We should probably try to use only the URI,
1681 * instead of using a filename.
1683 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1685 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1688 file_id = g_open (filename, O_RDONLY, 0);
1689 if (file_id != -1) {
1690 TnyMimePart *mime_part;
1692 const gchar *mime_type;
1695 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1696 mime_type = gnome_vfs_get_mime_type(filename);
1698 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1700 mime_part = tny_platform_factory_new_mime_part
1701 (modest_runtime_get_platform_factory ());
1702 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1704 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1706 content_id = g_strdup_printf ("%d", priv->last_cid);
1707 tny_mime_part_set_content_id (mime_part, content_id);
1708 g_free (content_id);
1711 basename = g_path_get_basename (filename);
1712 tny_mime_part_set_filename (mime_part, basename);
1715 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1716 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1718 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1719 gtk_widget_show_all (priv->attachments_caption);
1720 } else if (file_id == -1) {
1722 g_warning("file to be attached does not exist: %s", filename);
1730 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1733 ModestMsgEditWindowPrivate *priv;
1734 gboolean clean_list = FALSE;
1736 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1737 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1739 if (att_list == NULL) {
1740 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1744 if (att_list == NULL) {
1745 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1747 GtkWidget *confirmation_dialog = NULL;
1748 gboolean dialog_response;
1750 gchar *message = NULL;
1751 const gchar *filename = NULL;
1753 if (att_list->next == NULL) {
1754 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1758 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1759 att_list->next == NULL), filename);
1760 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1762 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1763 gtk_widget_destroy (confirmation_dialog);
1764 if (!dialog_response) {
1766 g_list_free (att_list);
1769 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1771 for (node = att_list; node != NULL; node = g_list_next (node)) {
1772 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1773 const gchar *att_id;
1774 priv->attachments = g_list_remove (priv->attachments, mime_part);
1776 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1778 if (priv->attachments == NULL)
1779 gtk_widget_hide (priv->attachments_caption);
1780 att_id = tny_mime_part_get_content_id (mime_part);
1782 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1784 g_object_unref (mime_part);
1785 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1790 g_list_free (att_list);
1794 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1797 ModestMsgEditWindowPrivate *priv;
1798 GdkColor *new_color;
1799 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1801 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1802 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1805 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1807 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1809 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1811 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1816 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1819 ModestMsgEditWindowPrivate *priv;
1820 gint new_size_index;
1821 ModestMsgEditWindow *window;
1824 window = MODEST_MSG_EDIT_WINDOW (userdata);
1825 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1826 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1828 if (gtk_check_menu_item_get_active (menu_item)) {
1830 WPTextBufferFormat format;
1832 memset (&format, 0, sizeof (format));
1833 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
1835 label = gtk_bin_get_child (GTK_BIN (menu_item));
1837 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1838 format.cs.font_size = TRUE;
1839 format.cs.text_position = TRUE;
1840 format.cs.font = TRUE;
1841 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1842 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
1844 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1845 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1846 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1848 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1849 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1850 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1856 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1859 ModestMsgEditWindowPrivate *priv;
1860 gint new_font_index;
1861 ModestMsgEditWindow *window;
1864 window = MODEST_MSG_EDIT_WINDOW (userdata);
1865 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1866 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1868 if (gtk_check_menu_item_get_active (menu_item)) {
1871 label = gtk_bin_get_child (GTK_BIN (menu_item));
1873 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1875 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1876 (gpointer) new_font_index))
1877 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1879 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1880 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1881 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1887 modest_msg_edit_window_set_zoom (ModestWindow *window,
1890 ModestMsgEditWindowPrivate *priv;
1891 ModestWindowPrivate *parent_priv;
1892 GtkRadioAction *zoom_radio_action;
1894 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1896 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1897 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1898 priv->zoom_level = zoom;
1899 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom*DEFAULT_FONT_SCALE);
1901 /* Zoom level menu options should be updated with the current zoom level */
1902 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1903 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1904 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1905 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1906 /* FIXME: Not availible before Gtk 2.10 */
1908 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1913 modest_msg_edit_window_get_zoom (ModestWindow *window)
1915 ModestMsgEditWindowPrivate *priv;
1917 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1919 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1920 return priv->zoom_level;
1924 zoom_allowed (ModestMsgEditWindow *window)
1928 focus = gtk_window_get_focus (GTK_WINDOW (window));
1929 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1933 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1935 ModestWindowPrivate *parent_priv;
1936 GtkRadioAction *zoom_radio_action;
1937 GSList *group, *node;
1939 /* First we check if the text view is focused. If not, zooming is not allowed */
1940 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1941 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1945 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1946 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1947 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1949 group = gtk_radio_action_get_group (zoom_radio_action);
1951 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1952 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1956 for (node = group; node != NULL; node = g_slist_next (node)) {
1957 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1958 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1966 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1968 ModestWindowPrivate *parent_priv;
1969 GtkRadioAction *zoom_radio_action;
1970 GSList *group, *node;
1972 /* First we check if the text view is focused. If not, zooming is not allowed */
1973 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1974 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1978 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1979 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1980 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1982 group = gtk_radio_action_get_group (zoom_radio_action);
1984 for (node = group; node != NULL; node = g_slist_next (node)) {
1985 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1986 if (node->next != NULL) {
1987 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1990 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1998 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
2000 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
2001 ModestWindowPrivate *parent_priv;
2002 ModestWindowMgr *mgr;
2003 gboolean is_fullscreen;
2004 GtkAction *fs_toggle_action;
2007 mgr = modest_runtime_get_window_mgr ();
2008 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
2010 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
2012 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2013 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2014 if (is_fullscreen != active)
2015 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2023 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
2025 ModestWindowPrivate *parent_priv;
2026 GtkAction *fs_toggle_action;
2029 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2031 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2032 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
2033 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
2037 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2040 ModestMsgEditWindowPrivate *priv = NULL;
2041 const gchar *recipients;
2042 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2044 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2045 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2046 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
2047 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2048 gtk_widget_show (priv->cc_caption);
2050 gtk_widget_hide (priv->cc_caption);
2051 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2055 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2058 ModestMsgEditWindowPrivate *priv = NULL;
2059 const gchar *recipients;
2060 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2062 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2063 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2064 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2065 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2066 gtk_widget_show (priv->bcc_caption);
2068 gtk_widget_hide (priv->bcc_caption);
2069 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2073 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2074 ModestRecptEditor *editor)
2076 ModestMsgEditWindowPrivate *priv;
2078 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2079 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2080 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2082 if (editor == NULL) {
2083 GtkWidget *view_focus;
2084 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2086 /* This code should be kept in sync with ModestRecptEditor. The
2087 textview inside the recpt editor is the one that really gets the
2088 focus. As it's inside a scrolled window, and this one inside the
2089 hbox recpt editor inherits from, we'll need to go up in the
2090 hierarchy to know if the text view is part of the recpt editor
2091 or if it's a different text entry */
2093 if (gtk_widget_get_parent (view_focus)) {
2094 GtkWidget *first_parent;
2096 first_parent = gtk_widget_get_parent (view_focus);
2097 if (gtk_widget_get_parent (first_parent) &&
2098 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2099 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2104 editor = MODEST_RECPT_EDITOR (priv->to_field);
2108 modest_address_book_select_addresses (editor);
2113 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2115 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2117 modest_msg_edit_window_open_addressbook (window, NULL);
2121 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2122 gboolean show_toolbar)
2124 ModestWindowPrivate *parent_priv;
2126 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2127 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2129 /* FIXME: we can not just use the code of
2130 modest_msg_edit_window_setup_toolbar because it has a
2131 mixture of both initialization and creation code. */
2134 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2136 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2140 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2141 TnyHeaderFlags priority_flags)
2143 ModestMsgEditWindowPrivate *priv;
2144 ModestWindowPrivate *parent_priv;
2146 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2148 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2149 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2150 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2152 if (priv->priority_flags != priority_flags) {
2153 GtkAction *priority_action = NULL;
2155 priv->priority_flags = priority_flags;
2157 switch (priority_flags) {
2158 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2159 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2160 gtk_widget_show (priv->priority_icon);
2161 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2162 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2164 case TNY_HEADER_FLAG_LOW_PRIORITY:
2165 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2166 gtk_widget_show (priv->priority_icon);
2167 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2168 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2171 gtk_widget_hide (priv->priority_icon);
2172 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2173 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2176 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2177 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2182 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2185 ModestMsgEditWindowPrivate *priv;
2186 ModestWindowPrivate *parent_priv;
2187 gint current_format;
2189 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2191 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2192 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2194 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2195 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2197 if (current_format != file_format) {
2198 switch (file_format) {
2199 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2200 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2202 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2206 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2207 response = gtk_dialog_run (GTK_DIALOG (dialog));
2208 gtk_widget_destroy (dialog);
2209 if (response == GTK_RESPONSE_OK) {
2210 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2212 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2213 toggle_action_set_active_block_notify (action, TRUE);
2218 update_dimmed (window);
2223 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2226 ModestMsgEditWindowPrivate *priv;
2227 WPTextBufferFormat oldfmt, fmt;
2228 gint old_position = 0;
2232 GdkColor *color = NULL;
2233 gboolean bold, bold_set, italic, italic_set;
2234 gboolean underline, underline_set;
2235 gboolean strikethrough, strikethrough_set;
2236 gboolean position_set;
2237 gboolean font_size_set, font_set, color_set;
2240 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2241 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2243 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2245 /* First we get the currently selected font information */
2246 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2247 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2249 switch (oldfmt.text_position) {
2250 case TEXT_POSITION_NORMAL:
2253 case TEXT_POSITION_SUPERSCRIPT:
2261 g_object_set (G_OBJECT (dialog),
2262 "bold", oldfmt.bold != FALSE,
2263 "bold-set", !oldfmt.cs.bold,
2264 "underline", oldfmt.underline != FALSE,
2265 "underline-set", !oldfmt.cs.underline,
2266 "italic", oldfmt.italic != FALSE,
2267 "italic-set", !oldfmt.cs.italic,
2268 "strikethrough", oldfmt.strikethrough != FALSE,
2269 "strikethrough-set", !oldfmt.cs.strikethrough,
2270 "color", &oldfmt.color,
2271 "color-set", !oldfmt.cs.color,
2272 "size", wp_font_size[oldfmt.font_size],
2273 "size-set", !oldfmt.cs.font_size,
2274 "position", old_position,
2275 "position-set", !oldfmt.cs.text_position,
2276 "family", wp_get_font_name (oldfmt.font),
2277 "family-set", !oldfmt.cs.font,
2280 gtk_widget_show_all (dialog);
2281 response = gtk_dialog_run (GTK_DIALOG (dialog));
2282 if (response == GTK_RESPONSE_OK) {
2284 g_object_get( dialog,
2286 "bold-set", &bold_set,
2287 "underline", &underline,
2288 "underline-set", &underline_set,
2290 "italic-set", &italic_set,
2291 "strikethrough", &strikethrough,
2292 "strikethrough-set", &strikethrough_set,
2294 "color-set", &color_set,
2296 "size-set", &font_size_set,
2297 "family", &font_name,
2298 "family-set", &font_set,
2299 "position", &position,
2300 "position-set", &position_set,
2305 if (response == GTK_RESPONSE_OK) {
2306 memset(&fmt, 0, sizeof(fmt));
2312 fmt.italic = italic;
2313 fmt.cs.italic = TRUE;
2315 if (underline_set) {
2316 fmt.underline = underline;
2317 fmt.cs.underline = TRUE;
2319 if (strikethrough_set) {
2320 fmt.strikethrough = strikethrough;
2321 fmt.cs.strikethrough = TRUE;
2326 ? TEXT_POSITION_NORMAL
2327 : ( ( position == 1 )
2328 ? TEXT_POSITION_SUPERSCRIPT
2329 : TEXT_POSITION_SUBSCRIPT );
2330 fmt.cs.text_position = TRUE;
2334 fmt.cs.color = TRUE;
2337 fmt.font = wp_get_font_index(font_name,
2342 if (font_size_set) {
2343 fmt.font_size = wp_get_font_size_index(
2344 font_size, DEFAULT_FONT_SIZE);
2345 fmt.cs.font_size = TRUE;
2347 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2349 gtk_widget_destroy (dialog);
2351 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2355 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2357 ModestMsgEditWindowPrivate *priv;
2359 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2360 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2362 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2364 update_dimmed (window);
2369 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2371 ModestMsgEditWindowPrivate *priv;
2373 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2374 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2376 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2378 update_dimmed (window);
2383 update_dimmed (ModestMsgEditWindow *window)
2385 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2386 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2390 gboolean editor_focused;
2392 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2393 editor_focused = gtk_widget_is_focus (priv->msg_body);
2395 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2396 gtk_action_set_sensitive (action, rich_text && editor_focused);
2397 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2398 gtk_action_set_sensitive (action, rich_text && editor_focused);
2399 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2400 gtk_action_set_sensitive (action, rich_text && editor_focused);
2401 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2402 gtk_action_set_sensitive (action, rich_text && editor_focused);
2403 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2404 gtk_action_set_sensitive (action, rich_text && editor_focused);
2405 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2406 gtk_action_set_sensitive (action, rich_text && editor_focused);
2407 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2408 gtk_action_set_sensitive (action, rich_text && editor_focused);
2409 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2410 gtk_action_set_sensitive (action, rich_text && editor_focused);
2411 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2412 gtk_action_set_sensitive (action, rich_text && editor_focused);
2413 widget = priv->font_color_button;
2414 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2415 widget = priv->font_size_toolitem;
2416 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2417 widget = priv->font_face_toolitem;
2418 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2422 setup_insensitive_handlers (ModestMsgEditWindow *window)
2424 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2425 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2428 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2429 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2430 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2431 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2432 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2433 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2434 widget = priv->font_color_button;
2435 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2436 widget = priv->font_size_toolitem;
2437 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2438 widget = priv->font_face_toolitem;
2439 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2444 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2446 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2449 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2450 gtk_action_set_sensitive (action, can_undo);
2454 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2456 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2459 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu");
2460 gtk_action_set_sensitive (action, can_redo);
2464 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2467 GtkTextIter match_start, match_end;
2469 if (image_id == NULL)
2472 gtk_text_buffer_get_start_iter (buffer, &iter);
2474 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2475 GSList *tags = gtk_text_iter_get_tags (&match_start);
2477 for (node = tags; node != NULL; node = g_slist_next (node)) {
2478 GtkTextTag *tag = (GtkTextTag *) node->data;
2479 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2480 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2481 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2483 offset = gtk_text_iter_get_offset (&match_start);
2484 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2485 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2489 gtk_text_iter_forward_char (&iter);
2494 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2496 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2497 GtkTextIter real_start, real_end;
2498 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2500 if (gtk_text_iter_compare (start, end) > 0) {
2504 real_start = *start;
2508 GSList *tags = gtk_text_iter_get_tags (&real_start);
2510 for (node = tags; node != NULL; node = g_slist_next (node)) {
2511 GtkTextTag *tag = (GtkTextTag *) node->data;
2512 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2513 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2515 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2517 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2520 } while (gtk_text_iter_forward_char (&real_start)&&
2521 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2525 msg_body_focus (GtkWidget *focus,
2526 GdkEventFocus *event,
2530 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2535 recpt_field_changed (GtkTextBuffer *buffer,
2536 ModestMsgEditWindow *editor)
2538 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2539 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2540 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2541 gboolean dim = FALSE;
2544 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2545 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2546 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2548 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2549 gtk_text_buffer_get_char_count (cc_buffer) +
2550 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2552 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2553 gtk_action_set_sensitive (action, !dim);
2554 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2555 gtk_action_set_sensitive (action, !dim);
2559 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2561 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2565 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2567 gboolean rich_text, editor_focused;
2569 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2570 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2571 editor_focused = gtk_widget_is_focus (priv->msg_body);
2574 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2575 else if (!editor_focused)
2576 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2580 reset_modified (ModestMsgEditWindow *editor)
2582 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2583 GtkTextBuffer *buffer;
2585 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2586 gtk_text_buffer_set_modified (buffer, FALSE);
2587 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2588 gtk_text_buffer_set_modified (buffer, FALSE);
2589 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2590 gtk_text_buffer_set_modified (buffer, FALSE);
2591 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2595 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2597 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2598 GtkTextBuffer *buffer;
2600 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2601 if (gtk_text_buffer_get_modified (buffer))
2603 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2604 if (gtk_text_buffer_get_modified (buffer))
2606 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2607 if (gtk_text_buffer_get_modified (buffer))
2609 if (gtk_text_buffer_get_modified (priv->text_buffer))
2616 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2618 ModestMsgEditWindowPrivate *priv = NULL;
2620 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2621 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2623 /* check if there's no recipient added */
2624 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2625 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2626 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2627 /* no recipient contents, then select contacts */
2628 modest_msg_edit_window_open_addressbook (window, NULL);
2632 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2634 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2636 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2639 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2646 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2647 ModestMsgEditWindow *window)
2649 modest_msg_edit_window_attach_file (window);
2653 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2655 ModestMsgEditWindow *window)
2657 ModestWindowPrivate *parent_priv;
2658 ModestMsgEditWindowPrivate *priv;
2660 gboolean has_selection;
2662 GList *selected_attachments = NULL;
2663 gint n_att_selected = 0;
2665 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2666 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2667 has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL);
2668 focused = gtk_window_get_focus (GTK_WINDOW (window));
2670 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2671 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2672 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2673 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2675 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2676 n_att_selected = g_list_length (selected_attachments);
2677 g_list_free (selected_attachments);
2679 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2680 gtk_action_set_sensitive (action, n_att_selected == 1);
2682 update_paste_dimming (window);
2686 update_window_title (ModestMsgEditWindow *window)
2688 ModestMsgEditWindowPrivate *priv = NULL;
2689 const gchar *subject;
2691 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2692 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2693 if (subject == NULL || subject[0] == '\0')
2694 subject = _("mail_va_new_email");
2696 gtk_window_set_title (GTK_WINDOW (window), subject);
2701 subject_field_changed (GtkEditable *editable,
2702 ModestMsgEditWindow *window)
2704 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2705 update_window_title (window);
2706 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2710 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2713 ModestMsgEditWindowPrivate *priv = NULL;
2715 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2716 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2718 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2720 gtk_widget_show_all (priv->find_toolbar);
2721 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2723 gtk_widget_hide_all (priv->find_toolbar);
2724 gtk_widget_grab_focus (priv->msg_body);
2730 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2732 GtkTextIter *match_start,
2733 GtkTextIter *match_end)
2735 GtkTextIter end_iter;
2736 gchar *str_casefold;
2739 gchar *range_casefold;
2742 gboolean result = FALSE;
2749 gtk_text_iter_forward_to_end (&end_iter);
2751 str_casefold = g_utf8_casefold (str, -1);
2752 str_chars_n = strlen (str);
2754 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2755 range_casefold = g_utf8_casefold (range_text, -1);
2756 range_chars_n = strlen (range_casefold);
2758 if (range_chars_n < str_chars_n) {
2759 g_free (str_casefold);
2760 g_free (range_text);
2761 g_free (range_casefold);
2765 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2766 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2767 if (!g_utf8_collate (range_subtext, str_casefold)) {
2768 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2770 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2771 match_start, match_end, NULL);
2772 g_free (found_text);
2774 g_free (range_subtext);
2778 g_free (str_casefold);
2779 g_free (range_text);
2780 g_free (range_casefold);
2787 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2788 ModestMsgEditWindow *window)
2790 gchar *current_search = NULL;
2791 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2793 GtkTextIter selection_start, selection_end;
2794 GtkTextIter match_start, match_end;
2795 gboolean continue_search = FALSE;
2797 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2798 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2799 g_free (current_search);
2800 g_free (priv->last_search);
2801 priv->last_search = NULL;
2802 /* Information banner about empty search */
2803 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2807 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2808 continue_search = TRUE;
2810 g_free (priv->last_search);
2811 priv->last_search = g_strdup (current_search);
2814 if (continue_search) {
2815 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2816 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2817 &match_start, &match_end);
2819 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2821 GtkTextIter buffer_start;
2822 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2823 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2824 &match_start, &match_end);
2826 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2829 /* Mark as selected the string found in search */
2831 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2832 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2834 g_free (priv->last_search);
2835 priv->last_search = NULL;
2837 g_free (current_search);
2841 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2842 ModestMsgEditWindow *window)
2844 GtkToggleAction *toggle;
2845 ModestWindowPrivate *parent_priv;
2846 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2848 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2849 gtk_toggle_action_set_active (toggle, FALSE);
2854 update_paste_dimming (ModestMsgEditWindow *window)
2856 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2857 GtkAction *action = NULL;
2858 GtkClipboard *clipboard = NULL;
2862 focused = gtk_window_get_focus (GTK_WINDOW (window));
2864 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2865 active = gtk_clipboard_wait_is_text_available (clipboard);
2868 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2872 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2873 gtk_action_set_sensitive (action, active);
2878 update_select_all_dimming (ModestMsgEditWindow *window)
2881 gboolean dimmed = FALSE;
2883 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2885 focused = gtk_window_get_focus (GTK_WINDOW (window));
2886 if (GTK_IS_ENTRY (focused)) {
2887 const gchar *current_text;
2888 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2889 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2890 } else if (GTK_IS_TEXT_VIEW (focused)) {
2891 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2892 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2893 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2896 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2897 gtk_action_set_sensitive (action, !dimmed);
2901 update_zoom_dimming (ModestMsgEditWindow *window)
2904 gboolean dimmed = FALSE;
2906 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2908 focused = gtk_window_get_focus (GTK_WINDOW (window));
2909 dimmed = ! WP_IS_TEXT_VIEW (focused);
2910 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2911 gtk_action_set_sensitive (action, !dimmed);
2915 edit_menu_activated (GtkAction *action,
2918 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2920 update_select_all_dimming (window);
2921 update_paste_dimming (window);
2924 view_menu_activated (GtkAction *action,
2927 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2929 update_zoom_dimming (window);
2933 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2935 ModestMsgEditWindowPrivate *priv;
2937 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2942 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
2945 ModestMsgEditWindowPrivate *priv;
2947 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2953 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
2956 ModestMsgEditWindowPrivate *priv;
2957 TnyHeader *header = NULL;
2959 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2960 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
2962 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2963 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
2965 if (priv->draft_msg != NULL) {
2966 header = tny_msg_get_header (priv->draft_msg);
2967 if (TNY_IS_HEADER (header)) {
2968 modest_window_mgr_unregister_header (mgr, header);
2970 g_object_unref (priv->draft_msg);
2973 if (draft != NULL) {
2974 g_object_ref (draft);
2975 header = tny_msg_get_header (draft);
2976 if (TNY_IS_HEADER (header))
2977 modest_window_mgr_register_header (mgr, header);
2980 priv->draft_msg = draft;