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, *escaped_filename;
1516 TnyMimePart *mime_part;
1519 const gchar *mime_type = NULL;
1520 GnomeVFSURI *vfs_uri;
1522 vfs_uri = gnome_vfs_uri_new (uri);
1524 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
1525 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
1526 g_free (escaped_filename);
1527 gnome_vfs_uri_unref (vfs_uri);
1529 if (gnome_vfs_get_file_info (uri, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE
1530 | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
1532 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1534 mime_part = tny_platform_factory_new_mime_part
1535 (modest_runtime_get_platform_factory ());
1536 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1538 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1540 content_id = g_strdup_printf ("%d", priv->last_cid);
1541 tny_mime_part_set_content_id (mime_part, content_id);
1542 g_free (content_id);
1545 basename = g_path_get_basename (filename);
1546 tny_mime_part_set_filename (mime_part, basename);
1549 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1550 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1552 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1553 gtk_widget_show_all (priv->attachments_caption);
1554 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1557 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1558 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1559 unsigned char read_buffer[128];
1561 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1562 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1565 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1566 g_object_ref (pixbuf);
1567 gdk_pixbuf_loader_close (loader, NULL);
1568 g_object_unref (loader);
1570 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1571 GdkPixbuf *new_pixbuf;
1573 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1574 gdk_pixbuf_get_width (pixbuf);
1575 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1576 g_object_unref (pixbuf);
1577 pixbuf = new_pixbuf;
1580 if (pixbuf != NULL) {
1581 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1582 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1583 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1592 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1595 ModestMsgEditWindowPrivate *priv;
1596 GtkWidget *dialog = NULL;
1598 GSList *uris = NULL;
1601 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1603 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1604 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ti_select_attachment_title"));
1605 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1607 response = gtk_dialog_run (GTK_DIALOG (dialog));
1609 case GTK_RESPONSE_OK:
1610 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1615 gtk_widget_destroy (dialog);
1617 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1619 GnomeVFSHandle *handle = NULL;
1620 GnomeVFSResult result;
1622 uri = (const gchar *) uri_node->data;
1623 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1624 if (result == GNOME_VFS_OK) {
1625 TnyMimePart *mime_part;
1627 const gchar *mime_type = NULL;
1629 gchar *escaped_filename;
1632 GnomeVFSFileInfo info;
1633 GnomeVFSURI *vfs_uri;
1635 vfs_uri = gnome_vfs_uri_new (uri);
1638 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
1639 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
1640 g_free (escaped_filename);
1641 gnome_vfs_uri_unref (vfs_uri);
1643 if (gnome_vfs_get_file_info (uri,
1645 GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
1646 GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE)
1648 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1649 mime_part = tny_platform_factory_new_mime_part
1650 (modest_runtime_get_platform_factory ());
1651 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1653 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1655 content_id = g_strdup_printf ("%d", priv->last_cid);
1656 tny_mime_part_set_content_id (mime_part, content_id);
1657 g_free (content_id);
1660 basename = g_path_get_basename (filename);
1661 tny_mime_part_set_filename (mime_part, basename);
1664 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1665 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1667 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1668 gtk_widget_show_all (priv->attachments_caption);
1669 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1674 g_slist_foreach (uris, (GFunc) g_free, NULL);
1675 g_slist_free (uris);
1679 modest_msg_edit_window_attach_file_noninteractive (
1680 ModestMsgEditWindow *window,
1681 const gchar *file_uri)
1684 ModestMsgEditWindowPrivate *priv;
1686 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1688 if (file_uri && strlen(file_uri)) {
1691 /* TODO: We should probably try to use only the URI,
1692 * instead of using a filename.
1694 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1696 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1699 file_id = g_open (filename, O_RDONLY, 0);
1700 if (file_id != -1) {
1701 TnyMimePart *mime_part;
1703 const gchar *mime_type;
1706 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1707 mime_type = gnome_vfs_get_mime_type(filename);
1709 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1711 mime_part = tny_platform_factory_new_mime_part
1712 (modest_runtime_get_platform_factory ());
1713 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1715 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1717 content_id = g_strdup_printf ("%d", priv->last_cid);
1718 tny_mime_part_set_content_id (mime_part, content_id);
1719 g_free (content_id);
1722 basename = g_path_get_basename (filename);
1723 tny_mime_part_set_filename (mime_part, basename);
1726 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1727 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1729 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1730 gtk_widget_show_all (priv->attachments_caption);
1731 } else if (file_id == -1) {
1733 g_warning("file to be attached does not exist: %s", filename);
1741 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1744 ModestMsgEditWindowPrivate *priv;
1745 gboolean clean_list = FALSE;
1747 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1748 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1750 if (att_list == NULL) {
1751 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1755 if (att_list == NULL) {
1756 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1758 GtkWidget *confirmation_dialog = NULL;
1759 gboolean dialog_response;
1761 gchar *message = NULL;
1762 const gchar *filename = NULL;
1764 if (att_list->next == NULL) {
1765 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1769 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1770 att_list->next == NULL), filename);
1771 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1773 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1774 gtk_widget_destroy (confirmation_dialog);
1775 if (!dialog_response) {
1777 g_list_free (att_list);
1780 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1782 for (node = att_list; node != NULL; node = g_list_next (node)) {
1783 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1784 const gchar *att_id;
1785 priv->attachments = g_list_remove (priv->attachments, mime_part);
1787 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1789 if (priv->attachments == NULL)
1790 gtk_widget_hide (priv->attachments_caption);
1791 att_id = tny_mime_part_get_content_id (mime_part);
1793 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1795 g_object_unref (mime_part);
1796 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1801 g_list_free (att_list);
1805 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1808 ModestMsgEditWindowPrivate *priv;
1809 GdkColor *new_color;
1810 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1812 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1813 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1816 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1818 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1820 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1822 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1827 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1830 ModestMsgEditWindowPrivate *priv;
1831 gint new_size_index;
1832 ModestMsgEditWindow *window;
1835 window = MODEST_MSG_EDIT_WINDOW (userdata);
1836 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1837 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1839 if (gtk_check_menu_item_get_active (menu_item)) {
1841 WPTextBufferFormat format;
1843 memset (&format, 0, sizeof (format));
1844 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
1846 label = gtk_bin_get_child (GTK_BIN (menu_item));
1848 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1849 format.cs.font_size = TRUE;
1850 format.cs.text_position = TRUE;
1851 format.cs.font = TRUE;
1852 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1853 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
1855 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1856 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1857 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1859 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1860 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1861 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1867 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1870 ModestMsgEditWindowPrivate *priv;
1871 gint new_font_index;
1872 ModestMsgEditWindow *window;
1875 window = MODEST_MSG_EDIT_WINDOW (userdata);
1876 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1877 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1879 if (gtk_check_menu_item_get_active (menu_item)) {
1882 label = gtk_bin_get_child (GTK_BIN (menu_item));
1884 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1886 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1887 (gpointer) new_font_index))
1888 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1890 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1891 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1892 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1898 modest_msg_edit_window_set_zoom (ModestWindow *window,
1901 ModestMsgEditWindowPrivate *priv;
1902 ModestWindowPrivate *parent_priv;
1903 GtkRadioAction *zoom_radio_action;
1905 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1907 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1908 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1909 priv->zoom_level = zoom;
1910 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom*DEFAULT_FONT_SCALE);
1912 /* Zoom level menu options should be updated with the current zoom level */
1913 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1914 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1915 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1916 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1917 /* FIXME: Not availible before Gtk 2.10 */
1919 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1924 modest_msg_edit_window_get_zoom (ModestWindow *window)
1926 ModestMsgEditWindowPrivate *priv;
1928 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1930 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1931 return priv->zoom_level;
1935 zoom_allowed (ModestMsgEditWindow *window)
1939 focus = gtk_window_get_focus (GTK_WINDOW (window));
1940 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1944 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1946 ModestWindowPrivate *parent_priv;
1947 GtkRadioAction *zoom_radio_action;
1948 GSList *group, *node;
1950 /* First we check if the text view is focused. If not, zooming is not allowed */
1951 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1952 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1956 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1957 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1958 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1960 group = gtk_radio_action_get_group (zoom_radio_action);
1962 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1963 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1967 for (node = group; node != NULL; node = g_slist_next (node)) {
1968 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1969 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1977 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1979 ModestWindowPrivate *parent_priv;
1980 GtkRadioAction *zoom_radio_action;
1981 GSList *group, *node;
1983 /* First we check if the text view is focused. If not, zooming is not allowed */
1984 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1985 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1989 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1990 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1991 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1993 group = gtk_radio_action_get_group (zoom_radio_action);
1995 for (node = group; node != NULL; node = g_slist_next (node)) {
1996 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1997 if (node->next != NULL) {
1998 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
2001 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
2009 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
2011 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
2012 ModestWindowPrivate *parent_priv;
2013 ModestWindowMgr *mgr;
2014 gboolean is_fullscreen;
2015 GtkAction *fs_toggle_action;
2018 mgr = modest_runtime_get_window_mgr ();
2019 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
2021 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
2023 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2024 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2025 if (is_fullscreen != active)
2026 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2034 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
2036 ModestWindowPrivate *parent_priv;
2037 GtkAction *fs_toggle_action;
2040 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2042 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2043 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
2044 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
2048 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2051 ModestMsgEditWindowPrivate *priv = NULL;
2052 const gchar *recipients;
2053 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2055 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2056 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2057 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
2058 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2059 gtk_widget_show (priv->cc_caption);
2061 gtk_widget_hide (priv->cc_caption);
2062 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2066 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2069 ModestMsgEditWindowPrivate *priv = NULL;
2070 const gchar *recipients;
2071 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2073 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2074 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2075 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2076 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2077 gtk_widget_show (priv->bcc_caption);
2079 gtk_widget_hide (priv->bcc_caption);
2080 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2084 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2085 ModestRecptEditor *editor)
2087 ModestMsgEditWindowPrivate *priv;
2089 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2090 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2091 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2093 if (editor == NULL) {
2094 GtkWidget *view_focus;
2095 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2097 /* This code should be kept in sync with ModestRecptEditor. The
2098 textview inside the recpt editor is the one that really gets the
2099 focus. As it's inside a scrolled window, and this one inside the
2100 hbox recpt editor inherits from, we'll need to go up in the
2101 hierarchy to know if the text view is part of the recpt editor
2102 or if it's a different text entry */
2104 if (gtk_widget_get_parent (view_focus)) {
2105 GtkWidget *first_parent;
2107 first_parent = gtk_widget_get_parent (view_focus);
2108 if (gtk_widget_get_parent (first_parent) &&
2109 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2110 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2115 editor = MODEST_RECPT_EDITOR (priv->to_field);
2119 modest_address_book_select_addresses (editor);
2124 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2126 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2128 modest_msg_edit_window_open_addressbook (window, NULL);
2132 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2133 gboolean show_toolbar)
2135 ModestWindowPrivate *parent_priv;
2137 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2138 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2140 /* FIXME: we can not just use the code of
2141 modest_msg_edit_window_setup_toolbar because it has a
2142 mixture of both initialization and creation code. */
2145 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2147 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2151 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2152 TnyHeaderFlags priority_flags)
2154 ModestMsgEditWindowPrivate *priv;
2155 ModestWindowPrivate *parent_priv;
2157 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2159 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2160 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2161 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2163 if (priv->priority_flags != priority_flags) {
2164 GtkAction *priority_action = NULL;
2166 priv->priority_flags = priority_flags;
2168 switch (priority_flags) {
2169 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2170 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2171 gtk_widget_show (priv->priority_icon);
2172 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2173 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2175 case TNY_HEADER_FLAG_LOW_PRIORITY:
2176 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2177 gtk_widget_show (priv->priority_icon);
2178 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2179 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2182 gtk_widget_hide (priv->priority_icon);
2183 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2184 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2187 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2188 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2193 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2196 ModestMsgEditWindowPrivate *priv;
2197 ModestWindowPrivate *parent_priv;
2198 gint current_format;
2200 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2202 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2203 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2205 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2206 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2208 if (current_format != file_format) {
2209 switch (file_format) {
2210 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2211 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2213 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2217 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2218 response = gtk_dialog_run (GTK_DIALOG (dialog));
2219 gtk_widget_destroy (dialog);
2220 if (response == GTK_RESPONSE_OK) {
2221 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2223 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2224 toggle_action_set_active_block_notify (action, TRUE);
2229 update_dimmed (window);
2234 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2237 ModestMsgEditWindowPrivate *priv;
2238 WPTextBufferFormat oldfmt, fmt;
2239 gint old_position = 0;
2243 GdkColor *color = NULL;
2244 gboolean bold, bold_set, italic, italic_set;
2245 gboolean underline, underline_set;
2246 gboolean strikethrough, strikethrough_set;
2247 gboolean position_set;
2248 gboolean font_size_set, font_set, color_set;
2251 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2252 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2254 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2256 /* First we get the currently selected font information */
2257 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2258 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2260 switch (oldfmt.text_position) {
2261 case TEXT_POSITION_NORMAL:
2264 case TEXT_POSITION_SUPERSCRIPT:
2272 g_object_set (G_OBJECT (dialog),
2273 "bold", oldfmt.bold != FALSE,
2274 "bold-set", !oldfmt.cs.bold,
2275 "underline", oldfmt.underline != FALSE,
2276 "underline-set", !oldfmt.cs.underline,
2277 "italic", oldfmt.italic != FALSE,
2278 "italic-set", !oldfmt.cs.italic,
2279 "strikethrough", oldfmt.strikethrough != FALSE,
2280 "strikethrough-set", !oldfmt.cs.strikethrough,
2281 "color", &oldfmt.color,
2282 "color-set", !oldfmt.cs.color,
2283 "size", wp_font_size[oldfmt.font_size],
2284 "size-set", !oldfmt.cs.font_size,
2285 "position", old_position,
2286 "position-set", !oldfmt.cs.text_position,
2287 "family", wp_get_font_name (oldfmt.font),
2288 "family-set", !oldfmt.cs.font,
2291 gtk_widget_show_all (dialog);
2292 response = gtk_dialog_run (GTK_DIALOG (dialog));
2293 if (response == GTK_RESPONSE_OK) {
2295 g_object_get( dialog,
2297 "bold-set", &bold_set,
2298 "underline", &underline,
2299 "underline-set", &underline_set,
2301 "italic-set", &italic_set,
2302 "strikethrough", &strikethrough,
2303 "strikethrough-set", &strikethrough_set,
2305 "color-set", &color_set,
2307 "size-set", &font_size_set,
2308 "family", &font_name,
2309 "family-set", &font_set,
2310 "position", &position,
2311 "position-set", &position_set,
2316 if (response == GTK_RESPONSE_OK) {
2317 memset(&fmt, 0, sizeof(fmt));
2323 fmt.italic = italic;
2324 fmt.cs.italic = TRUE;
2326 if (underline_set) {
2327 fmt.underline = underline;
2328 fmt.cs.underline = TRUE;
2330 if (strikethrough_set) {
2331 fmt.strikethrough = strikethrough;
2332 fmt.cs.strikethrough = TRUE;
2337 ? TEXT_POSITION_NORMAL
2338 : ( ( position == 1 )
2339 ? TEXT_POSITION_SUPERSCRIPT
2340 : TEXT_POSITION_SUBSCRIPT );
2341 fmt.cs.text_position = TRUE;
2345 fmt.cs.color = TRUE;
2348 fmt.font = wp_get_font_index(font_name,
2353 if (font_size_set) {
2354 fmt.font_size = wp_get_font_size_index(
2355 font_size, DEFAULT_FONT_SIZE);
2356 fmt.cs.font_size = TRUE;
2358 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2360 gtk_widget_destroy (dialog);
2362 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2366 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2368 ModestMsgEditWindowPrivate *priv;
2370 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2371 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2373 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2375 update_dimmed (window);
2380 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2382 ModestMsgEditWindowPrivate *priv;
2384 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2385 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2387 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2389 update_dimmed (window);
2394 update_dimmed (ModestMsgEditWindow *window)
2396 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2397 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2401 gboolean editor_focused;
2403 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2404 editor_focused = gtk_widget_is_focus (priv->msg_body);
2406 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2407 gtk_action_set_sensitive (action, rich_text && editor_focused);
2408 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2409 gtk_action_set_sensitive (action, rich_text && editor_focused);
2410 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2411 gtk_action_set_sensitive (action, rich_text && editor_focused);
2412 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2413 gtk_action_set_sensitive (action, rich_text && editor_focused);
2414 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2415 gtk_action_set_sensitive (action, rich_text && editor_focused);
2416 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2417 gtk_action_set_sensitive (action, rich_text && editor_focused);
2418 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2419 gtk_action_set_sensitive (action, rich_text && editor_focused);
2420 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2421 gtk_action_set_sensitive (action, rich_text && editor_focused);
2422 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2423 gtk_action_set_sensitive (action, rich_text && editor_focused);
2424 widget = priv->font_color_button;
2425 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2426 widget = priv->font_size_toolitem;
2427 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2428 widget = priv->font_face_toolitem;
2429 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2433 setup_insensitive_handlers (ModestMsgEditWindow *window)
2435 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2436 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2439 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2440 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2441 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2442 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2443 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2444 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2445 widget = priv->font_color_button;
2446 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2447 widget = priv->font_size_toolitem;
2448 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2449 widget = priv->font_face_toolitem;
2450 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2455 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2457 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2460 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2461 gtk_action_set_sensitive (action, can_undo);
2465 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2467 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2470 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu");
2471 gtk_action_set_sensitive (action, can_redo);
2475 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2478 GtkTextIter match_start, match_end;
2480 if (image_id == NULL)
2483 gtk_text_buffer_get_start_iter (buffer, &iter);
2485 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2486 GSList *tags = gtk_text_iter_get_tags (&match_start);
2488 for (node = tags; node != NULL; node = g_slist_next (node)) {
2489 GtkTextTag *tag = (GtkTextTag *) node->data;
2490 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2491 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2492 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2494 offset = gtk_text_iter_get_offset (&match_start);
2495 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2496 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2500 gtk_text_iter_forward_char (&iter);
2505 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2507 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2508 GtkTextIter real_start, real_end;
2509 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2511 if (gtk_text_iter_compare (start, end) > 0) {
2515 real_start = *start;
2519 GSList *tags = gtk_text_iter_get_tags (&real_start);
2521 for (node = tags; node != NULL; node = g_slist_next (node)) {
2522 GtkTextTag *tag = (GtkTextTag *) node->data;
2523 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2524 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2526 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2528 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2531 } while (gtk_text_iter_forward_char (&real_start)&&
2532 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2536 msg_body_focus (GtkWidget *focus,
2537 GdkEventFocus *event,
2541 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2546 recpt_field_changed (GtkTextBuffer *buffer,
2547 ModestMsgEditWindow *editor)
2549 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2550 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2551 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2552 gboolean dim = FALSE;
2555 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2556 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2557 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2559 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2560 gtk_text_buffer_get_char_count (cc_buffer) +
2561 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2563 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2564 gtk_action_set_sensitive (action, !dim);
2565 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2566 gtk_action_set_sensitive (action, !dim);
2570 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2572 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2576 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2578 gboolean rich_text, editor_focused;
2580 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2581 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2582 editor_focused = gtk_widget_is_focus (priv->msg_body);
2585 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2586 else if (!editor_focused)
2587 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2591 reset_modified (ModestMsgEditWindow *editor)
2593 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2594 GtkTextBuffer *buffer;
2596 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2597 gtk_text_buffer_set_modified (buffer, FALSE);
2598 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2599 gtk_text_buffer_set_modified (buffer, FALSE);
2600 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2601 gtk_text_buffer_set_modified (buffer, FALSE);
2602 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2606 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2608 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2609 GtkTextBuffer *buffer;
2611 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2612 if (gtk_text_buffer_get_modified (buffer))
2614 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2615 if (gtk_text_buffer_get_modified (buffer))
2617 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2618 if (gtk_text_buffer_get_modified (buffer))
2620 if (gtk_text_buffer_get_modified (priv->text_buffer))
2627 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2629 ModestMsgEditWindowPrivate *priv = NULL;
2631 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2632 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2634 /* check if there's no recipient added */
2635 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2636 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2637 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2638 /* no recipient contents, then select contacts */
2639 modest_msg_edit_window_open_addressbook (window, NULL);
2643 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2645 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2647 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2650 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2657 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2658 ModestMsgEditWindow *window)
2660 modest_msg_edit_window_attach_file (window);
2664 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2666 ModestMsgEditWindow *window)
2668 ModestWindowPrivate *parent_priv;
2669 ModestMsgEditWindowPrivate *priv;
2671 gboolean has_selection;
2673 GList *selected_attachments = NULL;
2674 gint n_att_selected = 0;
2676 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2677 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2678 has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL);
2679 focused = gtk_window_get_focus (GTK_WINDOW (window));
2681 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2682 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2683 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2684 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2686 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2687 n_att_selected = g_list_length (selected_attachments);
2688 g_list_free (selected_attachments);
2690 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2691 gtk_action_set_sensitive (action, n_att_selected == 1);
2693 update_paste_dimming (window);
2697 update_window_title (ModestMsgEditWindow *window)
2699 ModestMsgEditWindowPrivate *priv = NULL;
2700 const gchar *subject;
2702 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2703 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2704 if (subject == NULL || subject[0] == '\0')
2705 subject = _("mail_va_new_email");
2707 gtk_window_set_title (GTK_WINDOW (window), subject);
2712 subject_field_changed (GtkEditable *editable,
2713 ModestMsgEditWindow *window)
2715 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2716 update_window_title (window);
2717 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2721 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2724 ModestMsgEditWindowPrivate *priv = NULL;
2726 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2727 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2729 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2731 gtk_widget_show_all (priv->find_toolbar);
2732 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2734 gtk_widget_hide_all (priv->find_toolbar);
2735 gtk_widget_grab_focus (priv->msg_body);
2741 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2743 GtkTextIter *match_start,
2744 GtkTextIter *match_end)
2746 GtkTextIter end_iter;
2747 gchar *str_casefold;
2750 gchar *range_casefold;
2753 gboolean result = FALSE;
2760 gtk_text_iter_forward_to_end (&end_iter);
2762 str_casefold = g_utf8_casefold (str, -1);
2763 str_chars_n = strlen (str);
2765 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2766 range_casefold = g_utf8_casefold (range_text, -1);
2767 range_chars_n = strlen (range_casefold);
2769 if (range_chars_n < str_chars_n) {
2770 g_free (str_casefold);
2771 g_free (range_text);
2772 g_free (range_casefold);
2776 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2777 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2778 if (!g_utf8_collate (range_subtext, str_casefold)) {
2779 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2781 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2782 match_start, match_end, NULL);
2783 g_free (found_text);
2785 g_free (range_subtext);
2789 g_free (str_casefold);
2790 g_free (range_text);
2791 g_free (range_casefold);
2798 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2799 ModestMsgEditWindow *window)
2801 gchar *current_search = NULL;
2802 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2804 GtkTextIter selection_start, selection_end;
2805 GtkTextIter match_start, match_end;
2806 gboolean continue_search = FALSE;
2808 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2809 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2810 g_free (current_search);
2811 g_free (priv->last_search);
2812 priv->last_search = NULL;
2813 /* Information banner about empty search */
2814 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2818 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2819 continue_search = TRUE;
2821 g_free (priv->last_search);
2822 priv->last_search = g_strdup (current_search);
2825 if (continue_search) {
2826 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2827 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2828 &match_start, &match_end);
2830 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2832 GtkTextIter buffer_start;
2833 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2834 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2835 &match_start, &match_end);
2837 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2840 /* Mark as selected the string found in search */
2842 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2843 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2845 g_free (priv->last_search);
2846 priv->last_search = NULL;
2848 g_free (current_search);
2852 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2853 ModestMsgEditWindow *window)
2855 GtkToggleAction *toggle;
2856 ModestWindowPrivate *parent_priv;
2857 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2859 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2860 gtk_toggle_action_set_active (toggle, FALSE);
2865 update_paste_dimming (ModestMsgEditWindow *window)
2867 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2868 GtkAction *action = NULL;
2869 GtkClipboard *clipboard = NULL;
2873 focused = gtk_window_get_focus (GTK_WINDOW (window));
2875 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2876 active = gtk_clipboard_wait_is_text_available (clipboard);
2879 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2883 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2884 gtk_action_set_sensitive (action, active);
2890 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2892 ModestMsgEditWindow *window)
2894 update_paste_dimming (window);
2898 update_select_all_dimming (ModestMsgEditWindow *window)
2901 gboolean dimmed = FALSE;
2903 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2905 focused = gtk_window_get_focus (GTK_WINDOW (window));
2906 if (GTK_IS_ENTRY (focused)) {
2907 const gchar *current_text;
2908 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2909 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2910 } else if (GTK_IS_TEXT_VIEW (focused)) {
2911 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2912 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2913 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2916 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2917 gtk_action_set_sensitive (action, !dimmed);
2921 update_zoom_dimming (ModestMsgEditWindow *window)
2924 gboolean dimmed = FALSE;
2926 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2928 focused = gtk_window_get_focus (GTK_WINDOW (window));
2929 dimmed = ! WP_IS_TEXT_VIEW (focused);
2930 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2931 gtk_action_set_sensitive (action, !dimmed);
2935 edit_menu_activated (GtkAction *action,
2938 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2940 update_select_all_dimming (window);
2943 view_menu_activated (GtkAction *action,
2946 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2948 update_zoom_dimming (window);
2952 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2954 ModestMsgEditWindowPrivate *priv;
2956 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2961 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
2964 ModestMsgEditWindowPrivate *priv;
2966 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2972 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
2975 ModestMsgEditWindowPrivate *priv;
2976 TnyHeader *header = NULL;
2978 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2979 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
2981 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2982 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
2984 if (priv->draft_msg != NULL) {
2985 header = tny_msg_get_header (priv->draft_msg);
2986 if (TNY_IS_HEADER (header)) {
2987 modest_window_mgr_unregister_header (mgr, header);
2989 g_object_unref (priv->draft_msg);
2992 if (draft != NULL) {
2993 g_object_ref (draft);
2994 header = tny_msg_get_header (draft);
2995 if (TNY_IS_HEADER (header))
2996 modest_window_mgr_register_header (mgr, header);
2999 priv->draft_msg = draft;