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 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
132 ModestMsgEditWindow *window);
133 static void update_window_title (ModestMsgEditWindow *window);
134 static void update_dimmed (ModestMsgEditWindow *window);
135 static void update_paste_dimming (ModestMsgEditWindow *window);
136 static void update_select_all_dimming (ModestMsgEditWindow *window);
137 static void update_zoom_dimming (ModestMsgEditWindow *window);
140 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
141 ModestMsgEditWindow *window);
142 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
143 ModestMsgEditWindow *window);
144 static gboolean gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
146 GtkTextIter *match_start,
147 GtkTextIter *match_end);
151 /* static gboolean */
152 /* on_key_pressed (GtkWidget *self, */
153 /* GdkEventKey *event, */
154 /* gpointer user_data); */
156 static void edit_menu_activated (GtkAction *action,
158 static void view_menu_activated (GtkAction *action,
161 /* list my signals */
168 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
169 struct _ModestMsgEditWindowPrivate {
171 GtkWidget *header_box;
173 ModestPairList *from_field_protos;
174 GtkWidget *from_field;
178 GtkWidget *bcc_field;
179 GtkWidget *subject_field;
180 GtkWidget *attachments_view;
181 GtkWidget *priority_icon;
182 GtkWidget *add_attachment_button;
184 GtkWidget *cc_caption;
185 GtkWidget *bcc_caption;
186 GtkWidget *attachments_caption;
188 GtkTextBuffer *text_buffer;
190 GtkWidget *font_size_toolitem;
191 GtkWidget *font_face_toolitem;
192 GtkWidget *font_color_button;
193 GSList *font_items_group;
194 GtkWidget *font_tool_button_label;
195 GSList *size_items_group;
196 GtkWidget *size_tool_button_label;
198 GtkWidget *find_toolbar;
202 GtkWidget *scroll_area;
207 TnyHeaderFlags priority_flags;
211 gulong clipboard_change_handler_id;
212 gulong system_clipboard_change_handler_id;
218 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
219 MODEST_TYPE_MSG_EDIT_WINDOW, \
220 ModestMsgEditWindowPrivate))
222 static GtkWindowClass *parent_class = NULL;
224 /* uncomment the following if you have defined any signals */
225 /* static guint signals[LAST_SIGNAL] = {0}; */
228 modest_msg_edit_window_get_type (void)
230 static GType my_type = 0;
232 static const GTypeInfo my_info = {
233 sizeof(ModestMsgEditWindowClass),
234 NULL, /* base init */
235 NULL, /* base finalize */
236 (GClassInitFunc) modest_msg_edit_window_class_init,
237 NULL, /* class finalize */
238 NULL, /* class data */
239 sizeof(ModestMsgEditWindow),
241 (GInstanceInitFunc) modest_msg_edit_window_init,
244 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
245 "ModestMsgEditWindow",
248 wp_text_buffer_library_init ();
254 save_state (ModestWindow *self)
256 modest_widget_memory_save (modest_runtime_get_conf(),
257 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
262 restore_settings (ModestMsgEditWindow *self)
264 modest_widget_memory_restore (modest_runtime_get_conf(),
265 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
270 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
272 GObjectClass *gobject_class;
273 ModestWindowClass *modest_window_class;
274 gobject_class = (GObjectClass*) klass;
275 modest_window_class = (ModestWindowClass*) klass;
277 parent_class = g_type_class_peek_parent (klass);
278 gobject_class->finalize = modest_msg_edit_window_finalize;
280 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
281 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
282 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
283 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
284 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
285 modest_window_class->save_state_func = save_state;
287 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
293 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
295 ModestMsgEditWindowPrivate *priv;
296 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
298 priv->msg_body = NULL;
299 priv->from_field = NULL;
300 priv->to_field = NULL;
301 priv->cc_field = NULL;
302 priv->bcc_field = NULL;
303 priv->subject_field = NULL;
304 priv->attachments = NULL;
306 priv->zoom_level = 1.0;
308 priv->cc_caption = NULL;
309 priv->bcc_caption = NULL;
311 priv->priority_flags = 0;
313 priv->find_toolbar = NULL;
314 priv->last_search = NULL;
316 priv->draft_msg = NULL;
317 priv->clipboard_change_handler_id = 0;
318 priv->system_clipboard_change_handler_id = 0;
323 /* FIXME: this is a dup from the one in gtk/ */
326 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
328 static ModestPairList*
329 get_transports (void)
331 GSList *transports = NULL;
333 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
334 GSList *accounts = modest_account_mgr_account_names (account_mgr,
335 TRUE /* only enabled accounts. */);
337 GSList *cursor = accounts;
339 gchar *account_name = cursor->data;
340 gchar *from_string = NULL;
342 from_string = modest_account_mgr_get_from_string (account_mgr,
346 if (from_string && account_name) {
347 gchar *name = account_name;
348 ModestPair *pair = modest_pair_new ((gpointer) name,
349 (gpointer) from_string , TRUE);
350 transports = g_slist_prepend (transports, pair);
353 cursor = cursor->next;
355 g_slist_free (accounts); /* only free the accounts, not the elements,
356 * because they are used in the pairlist */
362 init_window (ModestMsgEditWindow *obj)
364 GtkWidget *from_caption, *to_caption, *subject_caption;
365 GtkWidget *main_vbox;
366 ModestMsgEditWindowPrivate *priv;
368 GtkSizeGroup *size_group;
370 GtkWidget *subject_box;
371 GtkWidget *attachment_icon;
372 GtkWidget *window_box;
374 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
376 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
378 /* Note: This ModestPairList* must exist for as long as the combo
379 * that uses it, because the ModestComboBox uses the ID opaquely,
380 * so it can't know how to manage its memory. */
381 priv->from_field_protos = get_transports ();
383 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
385 priv->to_field = modest_recpt_editor_new ();
386 priv->cc_field = modest_recpt_editor_new ();
387 priv->bcc_field = modest_recpt_editor_new ();
388 subject_box = gtk_hbox_new (FALSE, 0);
389 priv->priority_icon = gtk_image_new ();
390 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
391 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
392 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
393 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
394 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
395 priv->add_attachment_button = gtk_button_new ();
396 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
397 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
398 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
399 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
400 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
401 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
402 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
403 priv->attachments_view = modest_attachments_view_new (NULL);
405 priv->header_box = gtk_vbox_new (FALSE, 0);
407 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
408 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
409 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
410 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
411 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
412 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
413 g_object_unref (size_group);
415 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
416 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
417 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
418 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
419 gtk_size_group_add_widget (size_group, priv->subject_field);
420 gtk_size_group_add_widget (size_group, priv->attachments_view);
421 g_object_unref (size_group);
423 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
424 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
425 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
426 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
427 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
428 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
429 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
432 priv->msg_body = wp_text_view_new ();
433 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
434 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
435 g_object_set (priv->text_buffer, "font_scale", DEFAULT_FONT_SCALE, NULL);
436 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
437 gtk_text_buffer_register_serialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
438 gtk_text_buffer_register_deserialize_tagset(GTK_TEXT_BUFFER(priv->text_buffer), "wp-text-buffer");
440 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
442 priv->find_toolbar = hildon_find_toolbar_new (NULL);
443 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
445 /* g_signal_connect (G_OBJECT (obj), "key_pressed", G_CALLBACK (on_key_pressed), NULL) */
447 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
448 G_CALLBACK (text_buffer_refresh_attributes), obj);
449 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
450 G_CALLBACK (text_buffer_delete_range), obj);
451 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
452 G_CALLBACK (text_buffer_can_undo), obj);
453 g_signal_connect (G_OBJECT (priv->text_buffer), "can-redo",
454 G_CALLBACK (text_buffer_can_redo), obj);
455 g_signal_connect (G_OBJECT (obj), "window-state-event",
456 G_CALLBACK (modest_msg_edit_window_window_state_event),
458 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
459 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
460 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
461 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
462 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
463 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
465 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
466 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
468 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
469 G_CALLBACK (msg_body_focus), obj);
470 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
471 G_CALLBACK (msg_body_focus), obj);
472 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
473 "changed", G_CALLBACK (recpt_field_changed), obj);
474 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
475 "changed", G_CALLBACK (recpt_field_changed), obj);
476 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
477 "changed", G_CALLBACK (recpt_field_changed), obj);
478 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
479 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
481 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
482 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
484 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
485 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
486 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
488 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
490 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
491 frame = gtk_frame_new (NULL);
492 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
494 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
495 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
496 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
498 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
499 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
500 gtk_widget_hide (priv->cc_caption);
502 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
503 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
504 gtk_widget_hide (priv->bcc_caption);
507 window_box = gtk_vbox_new (FALSE, 0);
508 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
509 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
510 gtk_container_add (GTK_CONTAINER(obj), window_box);
511 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
512 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
515 TODO: scroll_area was never instantiated.
516 Stop building without warnings-as-errors. murrayc.
517 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
518 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
521 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
522 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
523 priv->system_clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
524 G_CALLBACK (modest_msg_edit_window_system_clipboard_owner_change), obj);
530 modest_msg_edit_window_finalize (GObject *obj)
532 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
534 if (priv->clipboard_change_handler_id > 0) {
535 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
536 priv->clipboard_change_handler_id = 0;
539 if (priv->system_clipboard_change_handler_id > 0) {
540 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
541 priv->system_clipboard_change_handler_id);
542 priv->system_clipboard_change_handler_id = 0;
545 if (priv->draft_msg != NULL) {
546 TnyHeader *header = tny_msg_get_header (priv->draft_msg);
547 if (TNY_IS_HEADER (header)) {
548 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
549 modest_window_mgr_unregister_header (mgr, header);
551 g_object_unref (priv->draft_msg);
552 priv->draft_msg = NULL;
555 /* This had to stay alive for as long as the combobox that used it: */
556 modest_pair_list_free (priv->from_field_protos);
558 G_OBJECT_CLASS(parent_class)->finalize (obj);
562 menubar_to_menu (GtkUIManager *ui_manager)
564 GtkWidget *main_menu;
568 /* Create new main menu */
569 main_menu = gtk_menu_new();
571 /* Get the menubar from the UI manager */
572 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
574 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
578 menu = GTK_WIDGET (iter->data);
579 gtk_widget_reparent(menu, main_menu);
581 iter = g_list_next (iter);
588 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
591 const gchar *to, *cc, *bcc, *subject;
593 ModestMsgEditWindowPrivate *priv;
595 TnyHeaderFlags priority_flags;
596 TnyFolder *msg_folder;
598 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
599 g_return_if_fail (TNY_IS_MSG (msg));
601 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
603 header = tny_msg_get_header (msg);
604 to = tny_header_get_to (header);
605 cc = tny_header_get_cc (header);
606 bcc = tny_header_get_bcc (header);
607 subject = tny_header_get_subject (header);
608 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
611 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
613 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
614 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
615 gtk_widget_show (priv->cc_caption);
616 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_CC, NULL)) {
617 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
618 gtk_widget_hide (priv->cc_caption);
621 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
622 gtk_widget_set_no_show_all (priv->cc_caption, FALSE);
623 gtk_widget_show (priv->bcc_caption);
624 } else if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_BCC, NULL)) {
625 gtk_widget_set_no_show_all (priv->bcc_caption, FALSE);
626 gtk_widget_hide (priv->bcc_caption);
629 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
630 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
633 update_window_title (self);
635 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
636 body = modest_tny_msg_get_body (msg, TRUE);
638 if ((body == NULL)||(body[0] == '\0')) {
640 body = modest_text_utils_convert_to_html ("");
642 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
643 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
646 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
649 /* Get the default format required from configuration */
650 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
651 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
654 /* Set the default focus depending on having already a To: field or not */
655 if ((!to)||(*to == '\0')) {
656 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
658 gtk_widget_grab_focus (priv->msg_body);
661 /* TODO: lower priority, select in the From: combo to the
662 value that comes from msg <- not sure, should it be
665 /* Add attachments to the view */
666 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
667 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
668 if (priv->attachments == NULL) {
669 gtk_widget_hide (priv->attachments_caption);
671 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
672 gtk_widget_show_all (priv->attachments_caption);
675 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
676 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
678 reset_modified (self);
680 update_dimmed (self);
681 text_buffer_can_undo (priv->text_buffer, FALSE, self);
682 text_buffer_can_redo (priv->text_buffer, FALSE, self);
684 /* we should set a reference to the incoming message if it is a draft */
685 msg_folder = tny_msg_get_folder (msg);
687 if (modest_tny_folder_is_local_folder (msg_folder) &&
688 modest_tny_folder_get_local_folder_type (msg_folder) == TNY_FOLDER_TYPE_DRAFTS)
689 priv->draft_msg = g_object_ref(msg);
690 g_object_unref (msg_folder);
695 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
698 GList *item_children, *node;
699 GtkWidget *bin_child;
701 bin_child = gtk_bin_get_child (GTK_BIN(item));
703 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
705 for (node = item_children; node != NULL; node = g_list_next (node)) {
706 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
707 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
710 g_list_free (item_children);
714 menu_tool_button_dont_expand (GtkMenuToolButton *item)
717 GList *item_children, *node;
719 box = gtk_bin_get_child (GTK_BIN (item));
720 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
721 item_children = gtk_container_get_children (GTK_CONTAINER (box));
723 for (node = item_children; node != NULL; node = g_list_next (node)) {
724 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
725 if (GTK_IS_TOGGLE_BUTTON (node->data))
726 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
727 else if (GTK_IS_BUTTON (node->data))
728 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
730 g_list_free (item_children);
735 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
737 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
738 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
739 GtkWidget *placeholder;
740 GtkWidget *tool_item;
745 GtkWidget *sizes_menu;
746 GtkWidget *fonts_menu;
747 GSList *radio_group = NULL;
752 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
753 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
755 /* should we hide the toolbar? */
756 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
757 gtk_widget_hide (parent_priv->toolbar);
759 /* Font color placeholder */
760 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
761 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
764 tool_item = GTK_WIDGET (gtk_tool_item_new ());
765 priv->font_color_button = hildon_color_button_new ();
766 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
767 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
768 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
769 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
770 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
771 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
772 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
774 /* Font size and face placeholder */
775 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
776 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
778 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
779 priv->size_tool_button_label = gtk_label_new (NULL);
780 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
781 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
782 size_text,"</span>", NULL);
783 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
785 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
786 sizes_menu = gtk_menu_new ();
787 priv->size_items_group = NULL;
789 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
790 GtkWidget *size_menu_item;
792 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
793 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
794 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
795 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
796 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
797 gtk_widget_show (size_menu_item);
799 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
803 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
804 GtkWidget *item = (GtkWidget *) node->data;
805 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
809 priv->size_items_group = g_slist_reverse (priv->size_items_group);
810 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
811 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
812 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
813 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
814 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
815 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
816 priv->font_size_toolitem = tool_item;
819 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
820 priv->font_tool_button_label = gtk_label_new (NULL);
821 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
822 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
824 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
825 fonts_menu = gtk_menu_new ();
826 priv->font_items_group = NULL;
828 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
829 GtkWidget *font_menu_item;
830 GtkWidget *child_label;
832 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
833 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
834 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
835 wp_get_font_name (font_index), "</span>", NULL);
836 gtk_label_set_markup (GTK_LABEL (child_label), markup);
839 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
840 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
841 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
842 gtk_widget_show (font_menu_item);
844 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
847 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
848 GtkWidget *item = (GtkWidget *) node->data;
849 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
852 priv->font_items_group = g_slist_reverse (priv->font_items_group);
853 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
854 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
855 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
856 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
857 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
858 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
859 priv->font_face_toolitem = tool_item;
861 /* Set expand and homogeneous for remaining items */
862 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
863 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
864 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
865 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
866 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
867 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
868 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
869 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
870 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
878 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
881 ModestWindowPrivate *parent_priv;
882 ModestMsgEditWindowPrivate *priv;
883 GtkActionGroup *action_group;
884 GError *error = NULL;
885 GdkPixbuf *window_icon = NULL;
888 gboolean prefer_formatted;
890 ModestPair *account_pair = NULL;
892 g_return_val_if_fail (msg, NULL);
893 g_return_val_if_fail (account_name, NULL);
895 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
897 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
898 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
900 parent_priv->ui_manager = gtk_ui_manager_new();
901 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
902 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
904 /* Add common actions */
905 gtk_action_group_add_actions (action_group,
906 modest_msg_edit_action_entries,
907 G_N_ELEMENTS (modest_msg_edit_action_entries),
909 gtk_action_group_add_toggle_actions (action_group,
910 modest_msg_edit_toggle_action_entries,
911 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
913 gtk_action_group_add_radio_actions (action_group,
914 modest_msg_edit_alignment_radio_action_entries,
915 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
917 G_CALLBACK (modest_ui_actions_on_change_justify),
919 gtk_action_group_add_radio_actions (action_group,
920 modest_msg_edit_zoom_action_entries,
921 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
923 G_CALLBACK (modest_ui_actions_on_change_zoom),
925 gtk_action_group_add_radio_actions (action_group,
926 modest_msg_edit_priority_action_entries,
927 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
929 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
931 gtk_action_group_add_radio_actions (action_group,
932 modest_msg_edit_file_format_action_entries,
933 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
934 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
935 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
937 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
938 g_object_unref (action_group);
940 /* Load the UI definition */
941 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
944 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
945 g_clear_error (&error);
948 /* Add accelerators */
949 gtk_window_add_accel_group (GTK_WINDOW (obj),
950 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
953 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
954 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
957 init_window (MODEST_MSG_EDIT_WINDOW(obj));
959 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
961 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
963 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
965 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
967 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
968 if (account_pair != NULL)
969 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
971 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
973 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
975 /* Set window icon */
976 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
978 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
979 g_object_unref (window_icon);
982 /* Dim at start clipboard actions */
983 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
984 gtk_action_set_sensitive (action, FALSE);
985 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
986 gtk_action_set_sensitive (action, FALSE);
987 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
988 gtk_action_set_sensitive (action, FALSE);
990 /* Update select all */
991 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
992 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
993 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
994 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
995 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
997 /* set initial state of cc and bcc */
998 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
999 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1000 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
1001 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
1002 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1003 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
1005 /* Setup the file format */
1006 conf = modest_runtime_get_conf ();
1007 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
1009 g_clear_error (&error);
1010 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
1012 file_format = (prefer_formatted) ?
1013 MODEST_FILE_FORMAT_FORMATTED_TEXT :
1014 MODEST_FILE_FORMAT_PLAIN_TEXT;
1015 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
1017 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
1019 return (ModestWindow*) obj;
1023 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1025 GString **string_buffer = (GString **) user_data;
1027 *string_buffer = g_string_append (*string_buffer, buffer);
1033 * @result: A new string which should be freed with g_free().
1036 get_formatted_data (ModestMsgEditWindow *edit_window)
1038 ModestMsgEditWindowPrivate *priv;
1039 GString *string_buffer = g_string_new ("");
1041 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1043 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1045 return g_string_free (string_buffer, FALSE);
1050 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1053 const gchar *account_name;
1054 ModestMsgEditWindowPrivate *priv;
1056 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1058 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1060 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1061 g_return_val_if_fail (account_name, NULL);
1064 /* don't free these (except from) */
1065 data = g_slice_new0 (MsgData);
1066 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1068 data->account_name = g_strdup (account_name);
1069 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1070 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1071 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1072 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1073 if (priv->draft_msg) {
1074 data->draft_msg = g_object_ref (priv->draft_msg);
1076 data->draft_msg = NULL;
1079 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1081 gtk_text_buffer_get_bounds (buf, &b, &e);
1082 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1084 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1085 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1087 data->html_body = NULL;
1089 /* deep-copy the data */
1090 GList *cursor = priv->attachments;
1091 data->attachments = NULL;
1093 if (!(TNY_IS_MIME_PART(cursor->data))) {
1094 g_warning ("strange data in attachment list");
1097 data->attachments = g_list_append (data->attachments,
1098 g_object_ref (cursor->data));
1099 cursor = g_list_next (cursor);
1102 data->priority_flags = priv->priority_flags;
1109 unref_gobject (GObject *obj, gpointer data)
1111 if (!G_IS_OBJECT(obj))
1113 g_object_unref (obj);
1117 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1120 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1128 g_free (data->subject);
1129 g_free (data->plain_body);
1130 g_free (data->html_body);
1131 g_free (data->account_name);
1133 if (data->draft_msg != NULL) {
1134 g_object_unref (data->draft_msg);
1135 data->draft_msg = NULL;
1138 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1139 g_list_free (data->attachments);
1141 g_slice_free (MsgData, data);
1145 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1148 ModestMsgEditWindowPrivate *priv = NULL;
1149 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1151 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1153 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1155 return MODEST_MSG_EDIT_FORMAT_HTML;
1157 return MODEST_MSG_EDIT_FORMAT_TEXT;
1161 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1162 ModestMsgEditFormat format)
1164 ModestMsgEditWindowPrivate *priv;
1166 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1167 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1170 case MODEST_MSG_EDIT_FORMAT_HTML:
1171 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1173 case MODEST_MSG_EDIT_FORMAT_TEXT:
1174 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1177 g_return_if_reached ();
1181 ModestMsgEditFormatState *
1182 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1184 ModestMsgEditFormatState *format_state = NULL;
1185 ModestMsgEditWindowPrivate *priv;
1186 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1188 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1189 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1191 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1193 format_state = g_new0 (ModestMsgEditFormatState, 1);
1194 format_state->bold = buffer_format->bold&0x1;
1195 format_state->italics = buffer_format->italic&0x1;
1196 format_state->bullet = buffer_format->bullet&0x1;
1197 format_state->color = buffer_format->color;
1198 format_state->font_size = buffer_format->font_size;
1199 format_state->font_family = wp_get_font_name (buffer_format->font);
1200 format_state->justification = buffer_format->justification;
1201 g_free (buffer_format);
1203 return format_state;
1208 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1209 const ModestMsgEditFormatState *format_state)
1211 ModestMsgEditWindowPrivate *priv;
1212 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1213 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1214 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1215 g_return_if_fail (format_state != NULL);
1217 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1218 gtk_widget_grab_focus (priv->msg_body);
1219 buffer_format->bold = (format_state->bold != FALSE);
1220 buffer_format->italic = (format_state->italics != FALSE);
1221 buffer_format->color = format_state->color;
1222 buffer_format->font_size = format_state->font_size;
1223 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1224 buffer_format->justification = format_state->justification;
1225 buffer_format->bullet = format_state->bullet;
1227 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1229 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1230 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1231 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1232 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1233 buffer_format->cs.font = (buffer_format->font != current_format->font);
1234 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1235 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1237 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1238 if (buffer_format->cs.bold) {
1239 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1241 if (buffer_format->cs.italic) {
1242 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1244 if (buffer_format->cs.color) {
1245 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1247 if (buffer_format->cs.font_size) {
1248 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, (gpointer) (buffer_format->font_size));
1250 if (buffer_format->cs.justification) {
1251 switch (buffer_format->justification) {
1252 case GTK_JUSTIFY_LEFT:
1253 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1255 case GTK_JUSTIFY_CENTER:
1256 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1258 case GTK_JUSTIFY_RIGHT:
1259 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1266 if (buffer_format->cs.font) {
1267 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, (gpointer) (buffer_format->font));
1269 if (buffer_format->cs.bullet) {
1270 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1272 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1273 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1275 g_free (current_format);
1280 toggle_action_set_active_block_notify (GtkToggleAction *action,
1283 GSList *proxies = NULL;
1285 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1286 proxies != NULL; proxies = g_slist_next (proxies)) {
1287 GtkWidget *widget = (GtkWidget *) proxies->data;
1288 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1291 gtk_toggle_action_set_active (action, value);
1293 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1294 proxies != NULL; proxies = g_slist_next (proxies)) {
1295 GtkWidget *widget = (GtkWidget *) proxies->data;
1296 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1301 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1303 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1305 ModestWindowPrivate *parent_priv;
1306 ModestMsgEditWindowPrivate *priv;
1307 GtkWidget *new_size_menuitem;
1308 GtkWidget *new_font_menuitem;
1310 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1311 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1313 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1314 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1315 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1316 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1318 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1319 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1320 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1323 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1325 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1326 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1328 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1329 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1331 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1332 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1334 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1335 G_CALLBACK (modest_msg_edit_window_color_button_change),
1337 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1338 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1339 G_CALLBACK (modest_msg_edit_window_color_button_change),
1342 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1343 buffer_format->font_size))->data);
1344 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1348 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1349 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1350 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1352 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1353 G_CALLBACK (modest_msg_edit_window_size_change),
1355 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1356 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1357 G_CALLBACK (modest_msg_edit_window_size_change),
1361 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1362 buffer_format->font))->data);
1363 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1367 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1368 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1369 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1371 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1372 G_CALLBACK (modest_msg_edit_window_font_change),
1374 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1375 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1376 G_CALLBACK (modest_msg_edit_window_font_change),
1380 g_free (buffer_format);
1386 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1389 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1390 ModestMsgEditWindowPrivate *priv;
1391 GtkWidget *dialog = NULL;
1393 const GdkColor *new_color = NULL;
1395 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1396 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1398 #ifdef MODEST_HILDON_VERSION_0
1399 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1400 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1402 dialog = hildon_color_chooser_new ();
1403 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1404 #endif /*MODEST_HILDON_VERSION_0*/
1405 g_free (buffer_format);
1407 response = gtk_dialog_run (GTK_DIALOG (dialog));
1409 case GTK_RESPONSE_OK: {
1410 #ifdef MODEST_HILDON_VERSION_0
1411 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1414 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1416 #endif /*MODEST_HILDON_VERSION_0*/
1423 gtk_widget_destroy (dialog);
1425 if (new_color != NULL)
1426 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1431 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1434 ModestMsgEditWindowPrivate *priv;
1435 GtkWidget *dialog = NULL;
1437 GdkColor *old_color = NULL;
1438 const GdkColor *new_color = NULL;
1440 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1441 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1443 #ifdef MODEST_HILDON_VERSION_0
1444 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1445 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1447 dialog = hildon_color_chooser_new ();
1448 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1449 #endif /*MODEST_HILDON_VERSION_9*/
1451 response = gtk_dialog_run (GTK_DIALOG (dialog));
1453 case GTK_RESPONSE_OK: {
1454 #ifdef MODEST_HILDON_VERSION_0
1455 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1458 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1460 #endif /*MODEST_HILDON_VERSION_0*/
1466 gtk_widget_destroy (dialog);
1468 if (new_color != NULL)
1469 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1475 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1478 ModestMsgEditWindowPrivate *priv;
1479 GtkWidget *dialog = NULL;
1481 GSList *uris = NULL;
1482 GSList *uri_node = NULL;
1484 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1486 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1487 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1488 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1490 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1492 response = gtk_dialog_run (GTK_DIALOG (dialog));
1494 case GTK_RESPONSE_OK:
1495 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1500 gtk_widget_destroy (dialog);
1502 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1504 GnomeVFSHandle *handle = NULL;
1505 GnomeVFSResult result;
1506 GtkTextIter position;
1507 GtkTextMark *insert_mark;
1509 uri = (const gchar *) uri_node->data;
1510 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1511 if (result == GNOME_VFS_OK) {
1512 GdkPixbufLoader *loader;
1514 GnomeVFSFileInfo info;
1515 gchar *filename, *basename;
1516 TnyMimePart *mime_part;
1519 const gchar *mime_type = NULL;
1521 filename = g_filename_from_uri (uri, NULL, NULL);
1522 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1524 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1526 mime_part = tny_platform_factory_new_mime_part
1527 (modest_runtime_get_platform_factory ());
1528 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1530 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1532 content_id = g_strdup_printf ("%d", priv->last_cid);
1533 tny_mime_part_set_content_id (mime_part, content_id);
1534 g_free (content_id);
1537 basename = g_path_get_basename (filename);
1538 tny_mime_part_set_filename (mime_part, basename);
1541 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1542 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1544 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1545 gtk_widget_show_all (priv->attachments_caption);
1546 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1549 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1550 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1551 unsigned char read_buffer[128];
1553 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1554 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1557 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1558 g_object_ref (pixbuf);
1559 gdk_pixbuf_loader_close (loader, NULL);
1560 g_object_unref (loader);
1562 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1563 GdkPixbuf *new_pixbuf;
1565 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1566 gdk_pixbuf_get_width (pixbuf);
1567 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1568 g_object_unref (pixbuf);
1569 pixbuf = new_pixbuf;
1572 if (pixbuf != NULL) {
1573 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1574 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1575 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1584 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1587 ModestMsgEditWindowPrivate *priv;
1588 GtkWidget *dialog = NULL;
1590 GSList *uris = NULL;
1593 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1595 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1596 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
1597 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1599 response = gtk_dialog_run (GTK_DIALOG (dialog));
1601 case GTK_RESPONSE_OK:
1602 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1607 gtk_widget_destroy (dialog);
1609 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1611 GnomeVFSHandle *handle = NULL;
1612 GnomeVFSResult result;
1614 uri = (const gchar *) uri_node->data;
1615 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1616 if (result == GNOME_VFS_OK) {
1617 TnyMimePart *mime_part;
1619 const gchar *mime_type = NULL;
1623 GnomeVFSFileInfo info;
1625 filename = g_filename_from_uri (uri, NULL, NULL);
1627 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1628 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1629 mime_part = tny_platform_factory_new_mime_part
1630 (modest_runtime_get_platform_factory ());
1631 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1633 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1635 content_id = g_strdup_printf ("%d", priv->last_cid);
1636 tny_mime_part_set_content_id (mime_part, content_id);
1637 g_free (content_id);
1640 basename = g_path_get_basename (filename);
1641 tny_mime_part_set_filename (mime_part, basename);
1644 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1645 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1647 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1648 gtk_widget_show_all (priv->attachments_caption);
1649 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1654 g_slist_foreach (uris, (GFunc) g_free, NULL);
1655 g_slist_free (uris);
1659 modest_msg_edit_window_attach_file_noninteractive (
1660 ModestMsgEditWindow *window,
1661 const gchar *file_uri)
1664 ModestMsgEditWindowPrivate *priv;
1666 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1668 if (file_uri && strlen(file_uri)) {
1671 /* TODO: We should probably try to use only the URI,
1672 * instead of using a filename.
1674 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1676 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1679 file_id = g_open (filename, O_RDONLY, 0);
1680 if (file_id != -1) {
1681 TnyMimePart *mime_part;
1683 const gchar *mime_type;
1686 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1687 mime_type = gnome_vfs_get_mime_type(filename);
1689 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1691 mime_part = tny_platform_factory_new_mime_part
1692 (modest_runtime_get_platform_factory ());
1693 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1695 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1697 content_id = g_strdup_printf ("%d", priv->last_cid);
1698 tny_mime_part_set_content_id (mime_part, content_id);
1699 g_free (content_id);
1702 basename = g_path_get_basename (filename);
1703 tny_mime_part_set_filename (mime_part, basename);
1706 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1707 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1709 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1710 gtk_widget_show_all (priv->attachments_caption);
1711 } else if (file_id == -1) {
1713 g_warning("file to be attached does not exist: %s", filename);
1721 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1724 ModestMsgEditWindowPrivate *priv;
1725 gboolean clean_list = FALSE;
1727 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1728 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1730 if (att_list == NULL) {
1731 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1735 if (att_list == NULL) {
1736 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1738 GtkWidget *confirmation_dialog = NULL;
1739 gboolean dialog_response;
1741 gchar *message = NULL;
1742 const gchar *filename = NULL;
1744 if (att_list->next == NULL) {
1745 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1749 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1750 att_list->next == NULL), filename);
1751 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1753 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1754 gtk_widget_destroy (confirmation_dialog);
1755 if (!dialog_response) {
1757 g_list_free (att_list);
1760 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1762 for (node = att_list; node != NULL; node = g_list_next (node)) {
1763 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1764 const gchar *att_id;
1765 priv->attachments = g_list_remove (priv->attachments, mime_part);
1767 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1769 if (priv->attachments == NULL)
1770 gtk_widget_hide (priv->attachments_caption);
1771 att_id = tny_mime_part_get_content_id (mime_part);
1773 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1775 g_object_unref (mime_part);
1776 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1781 g_list_free (att_list);
1785 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1788 ModestMsgEditWindowPrivate *priv;
1789 GdkColor *new_color;
1790 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1792 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1793 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1796 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1798 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1800 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1802 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1807 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1810 ModestMsgEditWindowPrivate *priv;
1811 gint new_size_index;
1812 ModestMsgEditWindow *window;
1815 window = MODEST_MSG_EDIT_WINDOW (userdata);
1816 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1817 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1819 if (gtk_check_menu_item_get_active (menu_item)) {
1821 WPTextBufferFormat format;
1823 memset (&format, 0, sizeof (format));
1824 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
1826 label = gtk_bin_get_child (GTK_BIN (menu_item));
1828 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1829 format.cs.font_size = TRUE;
1830 format.cs.text_position = TRUE;
1831 format.cs.font = TRUE;
1832 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1833 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
1835 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1836 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1837 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1839 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1840 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1841 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1847 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1850 ModestMsgEditWindowPrivate *priv;
1851 gint new_font_index;
1852 ModestMsgEditWindow *window;
1855 window = MODEST_MSG_EDIT_WINDOW (userdata);
1856 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1857 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1859 if (gtk_check_menu_item_get_active (menu_item)) {
1862 label = gtk_bin_get_child (GTK_BIN (menu_item));
1864 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1866 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1867 (gpointer) new_font_index))
1868 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1870 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1871 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1872 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1878 modest_msg_edit_window_set_zoom (ModestWindow *window,
1881 ModestMsgEditWindowPrivate *priv;
1882 ModestWindowPrivate *parent_priv;
1883 GtkRadioAction *zoom_radio_action;
1885 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1887 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1888 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1889 priv->zoom_level = zoom;
1890 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom*DEFAULT_FONT_SCALE);
1892 /* Zoom level menu options should be updated with the current zoom level */
1893 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1894 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1895 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1896 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1897 /* FIXME: Not availible before Gtk 2.10 */
1899 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1904 modest_msg_edit_window_get_zoom (ModestWindow *window)
1906 ModestMsgEditWindowPrivate *priv;
1908 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1910 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1911 return priv->zoom_level;
1915 zoom_allowed (ModestMsgEditWindow *window)
1919 focus = gtk_window_get_focus (GTK_WINDOW (window));
1920 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1924 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1926 ModestWindowPrivate *parent_priv;
1927 GtkRadioAction *zoom_radio_action;
1928 GSList *group, *node;
1930 /* First we check if the text view is focused. If not, zooming is not allowed */
1931 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1932 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1936 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1937 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1938 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1940 group = gtk_radio_action_get_group (zoom_radio_action);
1942 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1943 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1947 for (node = group; node != NULL; node = g_slist_next (node)) {
1948 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1949 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1957 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1959 ModestWindowPrivate *parent_priv;
1960 GtkRadioAction *zoom_radio_action;
1961 GSList *group, *node;
1963 /* First we check if the text view is focused. If not, zooming is not allowed */
1964 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1965 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1969 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1970 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1971 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1973 group = gtk_radio_action_get_group (zoom_radio_action);
1975 for (node = group; node != NULL; node = g_slist_next (node)) {
1976 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1977 if (node->next != NULL) {
1978 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1981 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1989 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1991 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1992 ModestWindowPrivate *parent_priv;
1993 ModestWindowMgr *mgr;
1994 gboolean is_fullscreen;
1995 GtkAction *fs_toggle_action;
1998 mgr = modest_runtime_get_window_mgr ();
1999 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
2001 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
2003 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2004 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2005 if (is_fullscreen != active)
2006 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2014 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
2016 ModestWindowPrivate *parent_priv;
2017 GtkAction *fs_toggle_action;
2020 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2022 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2023 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
2024 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
2028 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2031 ModestMsgEditWindowPrivate *priv = NULL;
2032 const gchar *recipients;
2033 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2035 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2036 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2037 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
2038 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2039 gtk_widget_show (priv->cc_caption);
2041 gtk_widget_hide (priv->cc_caption);
2042 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2046 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2049 ModestMsgEditWindowPrivate *priv = NULL;
2050 const gchar *recipients;
2051 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2053 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2054 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2055 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2056 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2057 gtk_widget_show (priv->bcc_caption);
2059 gtk_widget_hide (priv->bcc_caption);
2060 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2064 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2065 ModestRecptEditor *editor)
2067 ModestMsgEditWindowPrivate *priv;
2069 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2070 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2071 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2073 if (editor == NULL) {
2074 GtkWidget *view_focus;
2075 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2077 /* This code should be kept in sync with ModestRecptEditor. The
2078 textview inside the recpt editor is the one that really gets the
2079 focus. As it's inside a scrolled window, and this one inside the
2080 hbox recpt editor inherits from, we'll need to go up in the
2081 hierarchy to know if the text view is part of the recpt editor
2082 or if it's a different text entry */
2084 if (gtk_widget_get_parent (view_focus)) {
2085 GtkWidget *first_parent;
2087 first_parent = gtk_widget_get_parent (view_focus);
2088 if (gtk_widget_get_parent (first_parent) &&
2089 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2090 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2095 editor = MODEST_RECPT_EDITOR (priv->to_field);
2099 modest_address_book_select_addresses (editor);
2104 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2106 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2108 modest_msg_edit_window_open_addressbook (window, NULL);
2112 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2113 gboolean show_toolbar)
2115 ModestWindowPrivate *parent_priv;
2117 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2118 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2120 /* FIXME: we can not just use the code of
2121 modest_msg_edit_window_setup_toolbar because it has a
2122 mixture of both initialization and creation code. */
2125 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2127 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2131 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2132 TnyHeaderFlags priority_flags)
2134 ModestMsgEditWindowPrivate *priv;
2135 ModestWindowPrivate *parent_priv;
2137 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2139 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2140 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2141 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2143 if (priv->priority_flags != priority_flags) {
2144 GtkAction *priority_action = NULL;
2146 priv->priority_flags = priority_flags;
2148 switch (priority_flags) {
2149 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2150 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2151 gtk_widget_show (priv->priority_icon);
2152 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2153 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2155 case TNY_HEADER_FLAG_LOW_PRIORITY:
2156 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2157 gtk_widget_show (priv->priority_icon);
2158 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2159 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2162 gtk_widget_hide (priv->priority_icon);
2163 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2164 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2167 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2168 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2173 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2176 ModestMsgEditWindowPrivate *priv;
2177 ModestWindowPrivate *parent_priv;
2178 gint current_format;
2180 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2182 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2183 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2185 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2186 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2188 if (current_format != file_format) {
2189 switch (file_format) {
2190 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2191 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2193 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2197 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2198 response = gtk_dialog_run (GTK_DIALOG (dialog));
2199 gtk_widget_destroy (dialog);
2200 if (response == GTK_RESPONSE_OK) {
2201 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2203 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2204 toggle_action_set_active_block_notify (action, TRUE);
2209 update_dimmed (window);
2214 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2217 ModestMsgEditWindowPrivate *priv;
2218 WPTextBufferFormat oldfmt, fmt;
2219 gint old_position = 0;
2223 GdkColor *color = NULL;
2224 gboolean bold, bold_set, italic, italic_set;
2225 gboolean underline, underline_set;
2226 gboolean strikethrough, strikethrough_set;
2227 gboolean position_set;
2228 gboolean font_size_set, font_set, color_set;
2231 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2232 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2234 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2236 /* First we get the currently selected font information */
2237 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2238 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2240 switch (oldfmt.text_position) {
2241 case TEXT_POSITION_NORMAL:
2244 case TEXT_POSITION_SUPERSCRIPT:
2252 g_object_set (G_OBJECT (dialog),
2253 "bold", oldfmt.bold != FALSE,
2254 "bold-set", !oldfmt.cs.bold,
2255 "underline", oldfmt.underline != FALSE,
2256 "underline-set", !oldfmt.cs.underline,
2257 "italic", oldfmt.italic != FALSE,
2258 "italic-set", !oldfmt.cs.italic,
2259 "strikethrough", oldfmt.strikethrough != FALSE,
2260 "strikethrough-set", !oldfmt.cs.strikethrough,
2261 "color", &oldfmt.color,
2262 "color-set", !oldfmt.cs.color,
2263 "size", wp_font_size[oldfmt.font_size],
2264 "size-set", !oldfmt.cs.font_size,
2265 "position", old_position,
2266 "position-set", !oldfmt.cs.text_position,
2267 "family", wp_get_font_name (oldfmt.font),
2268 "family-set", !oldfmt.cs.font,
2271 gtk_widget_show_all (dialog);
2272 response = gtk_dialog_run (GTK_DIALOG (dialog));
2273 if (response == GTK_RESPONSE_OK) {
2275 g_object_get( dialog,
2277 "bold-set", &bold_set,
2278 "underline", &underline,
2279 "underline-set", &underline_set,
2281 "italic-set", &italic_set,
2282 "strikethrough", &strikethrough,
2283 "strikethrough-set", &strikethrough_set,
2285 "color-set", &color_set,
2287 "size-set", &font_size_set,
2288 "family", &font_name,
2289 "family-set", &font_set,
2290 "position", &position,
2291 "position-set", &position_set,
2296 if (response == GTK_RESPONSE_OK) {
2297 memset(&fmt, 0, sizeof(fmt));
2303 fmt.italic = italic;
2304 fmt.cs.italic = TRUE;
2306 if (underline_set) {
2307 fmt.underline = underline;
2308 fmt.cs.underline = TRUE;
2310 if (strikethrough_set) {
2311 fmt.strikethrough = strikethrough;
2312 fmt.cs.strikethrough = TRUE;
2317 ? TEXT_POSITION_NORMAL
2318 : ( ( position == 1 )
2319 ? TEXT_POSITION_SUPERSCRIPT
2320 : TEXT_POSITION_SUBSCRIPT );
2321 fmt.cs.text_position = TRUE;
2325 fmt.cs.color = TRUE;
2328 fmt.font = wp_get_font_index(font_name,
2333 if (font_size_set) {
2334 fmt.font_size = wp_get_font_size_index(
2335 font_size, DEFAULT_FONT_SIZE);
2336 fmt.cs.font_size = TRUE;
2338 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2340 gtk_widget_destroy (dialog);
2342 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2346 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2348 ModestMsgEditWindowPrivate *priv;
2350 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2351 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2353 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2355 update_dimmed (window);
2360 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2362 ModestMsgEditWindowPrivate *priv;
2364 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2365 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2367 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2369 update_dimmed (window);
2374 update_dimmed (ModestMsgEditWindow *window)
2376 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2377 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2381 gboolean editor_focused;
2383 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2384 editor_focused = gtk_widget_is_focus (priv->msg_body);
2386 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2387 gtk_action_set_sensitive (action, rich_text && editor_focused);
2388 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2389 gtk_action_set_sensitive (action, rich_text && editor_focused);
2390 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2391 gtk_action_set_sensitive (action, rich_text && editor_focused);
2392 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2393 gtk_action_set_sensitive (action, rich_text && editor_focused);
2394 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2395 gtk_action_set_sensitive (action, rich_text && editor_focused);
2396 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2397 gtk_action_set_sensitive (action, rich_text && editor_focused);
2398 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2399 gtk_action_set_sensitive (action, rich_text && editor_focused);
2400 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2401 gtk_action_set_sensitive (action, rich_text && editor_focused);
2402 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2403 gtk_action_set_sensitive (action, rich_text && editor_focused);
2404 widget = priv->font_color_button;
2405 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2406 widget = priv->font_size_toolitem;
2407 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2408 widget = priv->font_face_toolitem;
2409 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2413 setup_insensitive_handlers (ModestMsgEditWindow *window)
2415 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2416 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2419 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2420 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2421 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2422 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2423 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2424 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2425 widget = priv->font_color_button;
2426 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2427 widget = priv->font_size_toolitem;
2428 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2429 widget = priv->font_face_toolitem;
2430 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2435 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2437 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2440 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2441 gtk_action_set_sensitive (action, can_undo);
2445 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2447 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2450 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu");
2451 gtk_action_set_sensitive (action, can_redo);
2455 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2458 GtkTextIter match_start, match_end;
2460 if (image_id == NULL)
2463 gtk_text_buffer_get_start_iter (buffer, &iter);
2465 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2466 GSList *tags = gtk_text_iter_get_tags (&match_start);
2468 for (node = tags; node != NULL; node = g_slist_next (node)) {
2469 GtkTextTag *tag = (GtkTextTag *) node->data;
2470 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2471 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2472 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2474 offset = gtk_text_iter_get_offset (&match_start);
2475 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2476 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2480 gtk_text_iter_forward_char (&iter);
2485 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2487 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2488 GtkTextIter real_start, real_end;
2489 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2491 if (gtk_text_iter_compare (start, end) > 0) {
2495 real_start = *start;
2499 GSList *tags = gtk_text_iter_get_tags (&real_start);
2501 for (node = tags; node != NULL; node = g_slist_next (node)) {
2502 GtkTextTag *tag = (GtkTextTag *) node->data;
2503 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2504 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2506 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2508 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2511 } while (gtk_text_iter_forward_char (&real_start)&&
2512 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2516 msg_body_focus (GtkWidget *focus,
2517 GdkEventFocus *event,
2521 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2526 recpt_field_changed (GtkTextBuffer *buffer,
2527 ModestMsgEditWindow *editor)
2529 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2530 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2531 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2532 gboolean dim = FALSE;
2535 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2536 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2537 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2539 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2540 gtk_text_buffer_get_char_count (cc_buffer) +
2541 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2543 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2544 gtk_action_set_sensitive (action, !dim);
2545 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2546 gtk_action_set_sensitive (action, !dim);
2550 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2552 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2556 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2558 gboolean rich_text, editor_focused;
2560 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2561 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2562 editor_focused = gtk_widget_is_focus (priv->msg_body);
2565 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2566 else if (!editor_focused)
2567 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2571 reset_modified (ModestMsgEditWindow *editor)
2573 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2574 GtkTextBuffer *buffer;
2576 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2577 gtk_text_buffer_set_modified (buffer, FALSE);
2578 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2579 gtk_text_buffer_set_modified (buffer, FALSE);
2580 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2581 gtk_text_buffer_set_modified (buffer, FALSE);
2582 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2586 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2588 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2589 GtkTextBuffer *buffer;
2591 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2592 if (gtk_text_buffer_get_modified (buffer))
2594 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2595 if (gtk_text_buffer_get_modified (buffer))
2597 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2598 if (gtk_text_buffer_get_modified (buffer))
2600 if (gtk_text_buffer_get_modified (priv->text_buffer))
2607 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2609 ModestMsgEditWindowPrivate *priv = NULL;
2611 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2612 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2614 /* check if there's no recipient added */
2615 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2616 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2617 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2618 /* no recipient contents, then select contacts */
2619 modest_msg_edit_window_open_addressbook (window, NULL);
2623 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2625 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2627 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2630 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2637 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2638 ModestMsgEditWindow *window)
2640 modest_msg_edit_window_attach_file (window);
2644 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2646 ModestMsgEditWindow *window)
2648 ModestWindowPrivate *parent_priv;
2649 ModestMsgEditWindowPrivate *priv;
2651 gboolean has_selection;
2653 GList *selected_attachments = NULL;
2654 gint n_att_selected = 0;
2656 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2657 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2658 has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL);
2659 focused = gtk_window_get_focus (GTK_WINDOW (window));
2661 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2662 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2663 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2664 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2666 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2667 n_att_selected = g_list_length (selected_attachments);
2668 g_list_free (selected_attachments);
2670 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2671 gtk_action_set_sensitive (action, n_att_selected == 1);
2673 update_paste_dimming (window);
2677 update_window_title (ModestMsgEditWindow *window)
2679 ModestMsgEditWindowPrivate *priv = NULL;
2680 const gchar *subject;
2682 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2683 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2684 if (subject == NULL || subject[0] == '\0')
2685 subject = _("mail_va_new_email");
2687 gtk_window_set_title (GTK_WINDOW (window), subject);
2692 subject_field_changed (GtkEditable *editable,
2693 ModestMsgEditWindow *window)
2695 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2696 update_window_title (window);
2697 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2701 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2704 ModestMsgEditWindowPrivate *priv = NULL;
2706 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2707 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2709 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2711 gtk_widget_show_all (priv->find_toolbar);
2712 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2714 gtk_widget_hide_all (priv->find_toolbar);
2715 gtk_widget_grab_focus (priv->msg_body);
2721 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2723 GtkTextIter *match_start,
2724 GtkTextIter *match_end)
2726 GtkTextIter end_iter;
2727 gchar *str_casefold;
2730 gchar *range_casefold;
2733 gboolean result = FALSE;
2740 gtk_text_iter_forward_to_end (&end_iter);
2742 str_casefold = g_utf8_casefold (str, -1);
2743 str_chars_n = strlen (str);
2745 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2746 range_casefold = g_utf8_casefold (range_text, -1);
2747 range_chars_n = strlen (range_casefold);
2749 if (range_chars_n < str_chars_n) {
2750 g_free (str_casefold);
2751 g_free (range_text);
2752 g_free (range_casefold);
2756 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2757 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2758 if (!g_utf8_collate (range_subtext, str_casefold)) {
2759 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2761 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2762 match_start, match_end, NULL);
2763 g_free (found_text);
2765 g_free (range_subtext);
2769 g_free (str_casefold);
2770 g_free (range_text);
2771 g_free (range_casefold);
2778 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2779 ModestMsgEditWindow *window)
2781 gchar *current_search = NULL;
2782 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2784 GtkTextIter selection_start, selection_end;
2785 GtkTextIter match_start, match_end;
2786 gboolean continue_search = FALSE;
2788 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2789 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2790 g_free (current_search);
2791 g_free (priv->last_search);
2792 priv->last_search = NULL;
2793 /* Information banner about empty search */
2794 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2798 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2799 continue_search = TRUE;
2801 g_free (priv->last_search);
2802 priv->last_search = g_strdup (current_search);
2805 if (continue_search) {
2806 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2807 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2808 &match_start, &match_end);
2810 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2812 GtkTextIter buffer_start;
2813 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2814 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2815 &match_start, &match_end);
2817 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2820 /* Mark as selected the string found in search */
2822 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2823 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2825 g_free (priv->last_search);
2826 priv->last_search = NULL;
2828 g_free (current_search);
2832 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2833 ModestMsgEditWindow *window)
2835 GtkToggleAction *toggle;
2836 ModestWindowPrivate *parent_priv;
2837 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2839 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2840 gtk_toggle_action_set_active (toggle, FALSE);
2845 update_paste_dimming (ModestMsgEditWindow *window)
2847 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2848 GtkAction *action = NULL;
2849 GtkClipboard *clipboard = NULL;
2853 focused = gtk_window_get_focus (GTK_WINDOW (window));
2855 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2856 active = gtk_clipboard_wait_is_text_available (clipboard);
2859 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2863 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2864 gtk_action_set_sensitive (action, active);
2870 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2872 ModestMsgEditWindow *window)
2874 update_paste_dimming (window);
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);
2923 view_menu_activated (GtkAction *action,
2926 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2928 update_zoom_dimming (window);
2932 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2934 ModestMsgEditWindowPrivate *priv;
2936 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2941 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
2944 ModestMsgEditWindowPrivate *priv;
2946 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2952 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
2955 ModestMsgEditWindowPrivate *priv;
2956 TnyHeader *header = NULL;
2958 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2959 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
2961 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2962 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
2964 if (priv->draft_msg != NULL) {
2965 header = tny_msg_get_header (priv->draft_msg);
2966 if (TNY_IS_HEADER (header)) {
2967 modest_window_mgr_unregister_header (mgr, header);
2969 g_object_unref (priv->draft_msg);
2972 if (draft != NULL) {
2973 g_object_ref (draft);
2974 header = tny_msg_get_header (draft);
2975 if (TNY_IS_HEADER (header))
2976 modest_window_mgr_register_header (mgr, header);
2979 priv->draft_msg = draft;