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);
977 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
979 /* Dim at start clipboard actions */
980 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
981 gtk_action_set_sensitive (action, FALSE);
982 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
983 gtk_action_set_sensitive (action, FALSE);
984 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
985 gtk_action_set_sensitive (action, FALSE);
987 /* Update select all */
988 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
989 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
990 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
991 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
992 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
994 /* set initial state of cc and bcc */
995 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
996 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
997 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
998 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
999 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1000 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
1002 /* Setup the file format */
1003 conf = modest_runtime_get_conf ();
1004 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
1006 g_clear_error (&error);
1007 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
1009 file_format = (prefer_formatted) ?
1010 MODEST_FILE_FORMAT_FORMATTED_TEXT :
1011 MODEST_FILE_FORMAT_PLAIN_TEXT;
1012 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
1014 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
1016 return (ModestWindow*) obj;
1020 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1022 GString **string_buffer = (GString **) user_data;
1024 *string_buffer = g_string_append (*string_buffer, buffer);
1030 * @result: A new string which should be freed with g_free().
1033 get_formatted_data (ModestMsgEditWindow *edit_window)
1035 ModestMsgEditWindowPrivate *priv;
1036 GString *string_buffer = g_string_new ("");
1038 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1040 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1042 return g_string_free (string_buffer, FALSE);
1047 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1050 const gchar *account_name;
1051 ModestMsgEditWindowPrivate *priv;
1053 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1055 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1057 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1058 g_return_val_if_fail (account_name, NULL);
1061 /* don't free these (except from) */
1062 data = g_slice_new0 (MsgData);
1063 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1065 data->account_name = g_strdup (account_name);
1066 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1067 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1068 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1069 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1070 if (priv->draft_msg) {
1071 data->draft_msg = g_object_ref (priv->draft_msg);
1073 data->draft_msg = NULL;
1076 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1078 gtk_text_buffer_get_bounds (buf, &b, &e);
1079 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1081 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1082 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1084 data->html_body = NULL;
1086 /* deep-copy the data */
1087 GList *cursor = priv->attachments;
1088 data->attachments = NULL;
1090 if (!(TNY_IS_MIME_PART(cursor->data))) {
1091 g_warning ("strange data in attachment list");
1094 data->attachments = g_list_append (data->attachments,
1095 g_object_ref (cursor->data));
1096 cursor = g_list_next (cursor);
1099 data->priority_flags = priv->priority_flags;
1106 unref_gobject (GObject *obj, gpointer data)
1108 if (!G_IS_OBJECT(obj))
1110 g_object_unref (obj);
1114 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1117 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1125 g_free (data->subject);
1126 g_free (data->plain_body);
1127 g_free (data->html_body);
1128 g_free (data->account_name);
1130 if (data->draft_msg != NULL) {
1131 g_object_unref (data->draft_msg);
1132 data->draft_msg = NULL;
1135 g_list_foreach (data->attachments, (GFunc)unref_gobject, NULL);
1136 g_list_free (data->attachments);
1138 g_slice_free (MsgData, data);
1142 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1145 ModestMsgEditWindowPrivate *priv = NULL;
1146 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1148 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1150 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1152 return MODEST_MSG_EDIT_FORMAT_HTML;
1154 return MODEST_MSG_EDIT_FORMAT_TEXT;
1158 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1159 ModestMsgEditFormat format)
1161 ModestMsgEditWindowPrivate *priv;
1163 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1164 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1167 case MODEST_MSG_EDIT_FORMAT_HTML:
1168 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1170 case MODEST_MSG_EDIT_FORMAT_TEXT:
1171 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1174 g_return_if_reached ();
1178 ModestMsgEditFormatState *
1179 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1181 ModestMsgEditFormatState *format_state = NULL;
1182 ModestMsgEditWindowPrivate *priv;
1183 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1185 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1186 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1188 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1190 format_state = g_new0 (ModestMsgEditFormatState, 1);
1191 format_state->bold = buffer_format->bold&0x1;
1192 format_state->italics = buffer_format->italic&0x1;
1193 format_state->bullet = buffer_format->bullet&0x1;
1194 format_state->color = buffer_format->color;
1195 format_state->font_size = buffer_format->font_size;
1196 format_state->font_family = wp_get_font_name (buffer_format->font);
1197 format_state->justification = buffer_format->justification;
1198 g_free (buffer_format);
1200 return format_state;
1205 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1206 const ModestMsgEditFormatState *format_state)
1208 ModestMsgEditWindowPrivate *priv;
1209 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1210 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1211 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1212 g_return_if_fail (format_state != NULL);
1214 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1215 gtk_widget_grab_focus (priv->msg_body);
1216 buffer_format->bold = (format_state->bold != FALSE);
1217 buffer_format->italic = (format_state->italics != FALSE);
1218 buffer_format->color = format_state->color;
1219 buffer_format->font_size = format_state->font_size;
1220 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1221 buffer_format->justification = format_state->justification;
1222 buffer_format->bullet = format_state->bullet;
1224 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1226 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1227 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1228 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1229 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1230 buffer_format->cs.font = (buffer_format->font != current_format->font);
1231 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1232 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1234 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1235 if (buffer_format->cs.bold) {
1236 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1238 if (buffer_format->cs.italic) {
1239 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1241 if (buffer_format->cs.color) {
1242 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1244 if (buffer_format->cs.font_size) {
1245 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, (gpointer) (buffer_format->font_size));
1247 if (buffer_format->cs.justification) {
1248 switch (buffer_format->justification) {
1249 case GTK_JUSTIFY_LEFT:
1250 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1252 case GTK_JUSTIFY_CENTER:
1253 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1255 case GTK_JUSTIFY_RIGHT:
1256 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1263 if (buffer_format->cs.font) {
1264 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT, (gpointer) (buffer_format->font));
1266 if (buffer_format->cs.bullet) {
1267 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1269 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1270 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1272 g_free (current_format);
1277 toggle_action_set_active_block_notify (GtkToggleAction *action,
1280 GSList *proxies = NULL;
1282 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1283 proxies != NULL; proxies = g_slist_next (proxies)) {
1284 GtkWidget *widget = (GtkWidget *) proxies->data;
1285 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1288 gtk_toggle_action_set_active (action, value);
1290 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1291 proxies != NULL; proxies = g_slist_next (proxies)) {
1292 GtkWidget *widget = (GtkWidget *) proxies->data;
1293 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1298 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1300 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1302 ModestWindowPrivate *parent_priv;
1303 ModestMsgEditWindowPrivate *priv;
1304 GtkWidget *new_size_menuitem;
1305 GtkWidget *new_font_menuitem;
1307 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1308 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1310 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1311 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1312 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1313 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1315 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1316 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1317 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1320 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1322 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1323 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1325 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1326 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1328 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1329 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1331 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1332 G_CALLBACK (modest_msg_edit_window_color_button_change),
1334 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1335 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1336 G_CALLBACK (modest_msg_edit_window_color_button_change),
1339 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1340 buffer_format->font_size))->data);
1341 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1345 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1346 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1347 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1349 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1350 G_CALLBACK (modest_msg_edit_window_size_change),
1352 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1353 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1354 G_CALLBACK (modest_msg_edit_window_size_change),
1358 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1359 buffer_format->font))->data);
1360 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1364 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1365 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1366 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1368 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1369 G_CALLBACK (modest_msg_edit_window_font_change),
1371 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1372 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1373 G_CALLBACK (modest_msg_edit_window_font_change),
1377 g_free (buffer_format);
1383 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1386 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1387 ModestMsgEditWindowPrivate *priv;
1388 GtkWidget *dialog = NULL;
1390 const GdkColor *new_color = NULL;
1392 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1393 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1395 #ifdef MODEST_HILDON_VERSION_0
1396 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1397 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1399 dialog = hildon_color_chooser_new ();
1400 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1401 #endif /*MODEST_HILDON_VERSION_0*/
1402 g_free (buffer_format);
1404 response = gtk_dialog_run (GTK_DIALOG (dialog));
1406 case GTK_RESPONSE_OK: {
1407 #ifdef MODEST_HILDON_VERSION_0
1408 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1411 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1413 #endif /*MODEST_HILDON_VERSION_0*/
1420 gtk_widget_destroy (dialog);
1422 if (new_color != NULL)
1423 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1428 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1431 ModestMsgEditWindowPrivate *priv;
1432 GtkWidget *dialog = NULL;
1434 GdkColor *old_color = NULL;
1435 const GdkColor *new_color = NULL;
1437 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1438 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1440 #ifdef MODEST_HILDON_VERSION_0
1441 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1442 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1444 dialog = hildon_color_chooser_new ();
1445 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1446 #endif /*MODEST_HILDON_VERSION_9*/
1448 response = gtk_dialog_run (GTK_DIALOG (dialog));
1450 case GTK_RESPONSE_OK: {
1451 #ifdef MODEST_HILDON_VERSION_0
1452 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1455 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1457 #endif /*MODEST_HILDON_VERSION_0*/
1463 gtk_widget_destroy (dialog);
1465 if (new_color != NULL)
1466 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1472 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1475 ModestMsgEditWindowPrivate *priv;
1476 GtkWidget *dialog = NULL;
1478 GSList *uris = NULL;
1479 GSList *uri_node = NULL;
1481 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1483 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1484 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1485 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1487 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1489 response = gtk_dialog_run (GTK_DIALOG (dialog));
1491 case GTK_RESPONSE_OK:
1492 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1497 gtk_widget_destroy (dialog);
1499 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1501 GnomeVFSHandle *handle = NULL;
1502 GnomeVFSResult result;
1503 GtkTextIter position;
1504 GtkTextMark *insert_mark;
1506 uri = (const gchar *) uri_node->data;
1507 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1508 if (result == GNOME_VFS_OK) {
1509 GdkPixbufLoader *loader;
1511 GnomeVFSFileInfo info;
1512 gchar *filename, *basename;
1513 TnyMimePart *mime_part;
1516 const gchar *mime_type = NULL;
1518 filename = g_filename_from_uri (uri, NULL, NULL);
1519 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1521 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1523 mime_part = tny_platform_factory_new_mime_part
1524 (modest_runtime_get_platform_factory ());
1525 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1527 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1529 content_id = g_strdup_printf ("%d", priv->last_cid);
1530 tny_mime_part_set_content_id (mime_part, content_id);
1531 g_free (content_id);
1534 basename = g_path_get_basename (filename);
1535 tny_mime_part_set_filename (mime_part, basename);
1538 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1539 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1541 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1542 gtk_widget_show_all (priv->attachments_caption);
1543 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1546 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1547 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1548 unsigned char read_buffer[128];
1550 readed = tny_stream_read (TNY_STREAM (stream), (char *) read_buffer, 128);
1551 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1554 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1555 g_object_ref (pixbuf);
1556 gdk_pixbuf_loader_close (loader, NULL);
1557 g_object_unref (loader);
1559 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1560 GdkPixbuf *new_pixbuf;
1562 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1563 gdk_pixbuf_get_width (pixbuf);
1564 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1565 g_object_unref (pixbuf);
1566 pixbuf = new_pixbuf;
1569 if (pixbuf != NULL) {
1570 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1571 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1572 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1581 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1584 ModestMsgEditWindowPrivate *priv;
1585 GtkWidget *dialog = NULL;
1587 GSList *uris = NULL;
1590 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1592 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1593 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1595 response = gtk_dialog_run (GTK_DIALOG (dialog));
1597 case GTK_RESPONSE_OK:
1598 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1603 gtk_widget_destroy (dialog);
1605 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1607 GnomeVFSHandle *handle = NULL;
1608 GnomeVFSResult result;
1610 uri = (const gchar *) uri_node->data;
1611 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1612 if (result == GNOME_VFS_OK) {
1613 TnyMimePart *mime_part;
1615 const gchar *mime_type = NULL;
1619 GnomeVFSFileInfo info;
1621 filename = g_filename_from_uri (uri, NULL, NULL);
1623 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1624 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1625 mime_part = tny_platform_factory_new_mime_part
1626 (modest_runtime_get_platform_factory ());
1627 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1629 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1631 content_id = g_strdup_printf ("%d", priv->last_cid);
1632 tny_mime_part_set_content_id (mime_part, content_id);
1633 g_free (content_id);
1636 basename = g_path_get_basename (filename);
1637 tny_mime_part_set_filename (mime_part, basename);
1640 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1641 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1643 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1644 gtk_widget_show_all (priv->attachments_caption);
1645 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1650 g_slist_foreach (uris, (GFunc) g_free, NULL);
1651 g_slist_free (uris);
1655 modest_msg_edit_window_attach_file_noninteractive (
1656 ModestMsgEditWindow *window,
1657 const gchar *file_uri)
1660 ModestMsgEditWindowPrivate *priv;
1662 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1664 if (file_uri && strlen(file_uri)) {
1667 /* TODO: We should probably try to use only the URI,
1668 * instead of using a filename.
1670 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1672 g_warning("%s: g_filename_from_uri('%s') failed.\n", __FUNCTION__, file_uri);
1675 file_id = g_open (filename, O_RDONLY, 0);
1676 if (file_id != -1) {
1677 TnyMimePart *mime_part;
1679 const gchar *mime_type;
1682 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1683 mime_type = gnome_vfs_get_mime_type(filename);
1685 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1687 mime_part = tny_platform_factory_new_mime_part
1688 (modest_runtime_get_platform_factory ());
1689 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1691 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1693 content_id = g_strdup_printf ("%d", priv->last_cid);
1694 tny_mime_part_set_content_id (mime_part, content_id);
1695 g_free (content_id);
1698 basename = g_path_get_basename (filename);
1699 tny_mime_part_set_filename (mime_part, basename);
1702 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1703 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1705 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1706 gtk_widget_show_all (priv->attachments_caption);
1707 } else if (file_id == -1) {
1709 g_warning("file to be attached does not exist: %s", filename);
1717 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1720 ModestMsgEditWindowPrivate *priv;
1721 gboolean clean_list = FALSE;
1723 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1724 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1726 if (att_list == NULL) {
1727 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1731 if (att_list == NULL) {
1732 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1734 GtkWidget *confirmation_dialog = NULL;
1735 gboolean dialog_response;
1737 gchar *message = NULL;
1738 const gchar *filename = NULL;
1740 if (att_list->next == NULL) {
1741 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1745 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1746 att_list->next == NULL), filename);
1747 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1749 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1750 gtk_widget_destroy (confirmation_dialog);
1751 if (!dialog_response) {
1753 g_list_free (att_list);
1756 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1758 for (node = att_list; node != NULL; node = g_list_next (node)) {
1759 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1760 const gchar *att_id;
1761 priv->attachments = g_list_remove (priv->attachments, mime_part);
1763 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1765 if (priv->attachments == NULL)
1766 gtk_widget_hide (priv->attachments_caption);
1767 att_id = tny_mime_part_get_content_id (mime_part);
1769 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1771 g_object_unref (mime_part);
1772 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1777 g_list_free (att_list);
1781 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1784 ModestMsgEditWindowPrivate *priv;
1785 GdkColor *new_color;
1786 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1788 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1789 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1792 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1794 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1796 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1798 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1803 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1806 ModestMsgEditWindowPrivate *priv;
1807 gint new_size_index;
1808 ModestMsgEditWindow *window;
1811 window = MODEST_MSG_EDIT_WINDOW (userdata);
1812 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1813 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1815 if (gtk_check_menu_item_get_active (menu_item)) {
1817 WPTextBufferFormat format;
1819 memset (&format, 0, sizeof (format));
1820 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &format, FALSE);
1822 label = gtk_bin_get_child (GTK_BIN (menu_item));
1824 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1825 format.cs.font_size = TRUE;
1826 format.cs.text_position = TRUE;
1827 format.cs.font = TRUE;
1828 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1829 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format); */
1831 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1832 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1833 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1835 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1836 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1837 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1843 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1846 ModestMsgEditWindowPrivate *priv;
1847 gint new_font_index;
1848 ModestMsgEditWindow *window;
1851 window = MODEST_MSG_EDIT_WINDOW (userdata);
1852 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1853 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1855 if (gtk_check_menu_item_get_active (menu_item)) {
1858 label = gtk_bin_get_child (GTK_BIN (menu_item));
1860 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1862 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1863 (gpointer) new_font_index))
1864 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1866 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1867 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1868 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1874 modest_msg_edit_window_set_zoom (ModestWindow *window,
1877 ModestMsgEditWindowPrivate *priv;
1878 ModestWindowPrivate *parent_priv;
1879 GtkRadioAction *zoom_radio_action;
1881 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1883 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1884 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1885 priv->zoom_level = zoom;
1886 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom*DEFAULT_FONT_SCALE);
1888 /* Zoom level menu options should be updated with the current zoom level */
1889 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1890 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1891 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1892 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1893 /* FIXME: Not availible before Gtk 2.10 */
1895 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1900 modest_msg_edit_window_get_zoom (ModestWindow *window)
1902 ModestMsgEditWindowPrivate *priv;
1904 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1906 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1907 return priv->zoom_level;
1911 zoom_allowed (ModestMsgEditWindow *window)
1915 focus = gtk_window_get_focus (GTK_WINDOW (window));
1916 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1920 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1922 ModestWindowPrivate *parent_priv;
1923 GtkRadioAction *zoom_radio_action;
1924 GSList *group, *node;
1926 /* First we check if the text view is focused. If not, zooming is not allowed */
1927 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1928 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1932 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1933 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1934 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1936 group = gtk_radio_action_get_group (zoom_radio_action);
1938 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1939 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1943 for (node = group; node != NULL; node = g_slist_next (node)) {
1944 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1945 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1953 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1955 ModestWindowPrivate *parent_priv;
1956 GtkRadioAction *zoom_radio_action;
1957 GSList *group, *node;
1959 /* First we check if the text view is focused. If not, zooming is not allowed */
1960 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1961 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1965 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1966 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1967 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1969 group = gtk_radio_action_get_group (zoom_radio_action);
1971 for (node = group; node != NULL; node = g_slist_next (node)) {
1972 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1973 if (node->next != NULL) {
1974 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1977 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1985 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1987 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1988 ModestWindowPrivate *parent_priv;
1989 ModestWindowMgr *mgr;
1990 gboolean is_fullscreen;
1991 GtkAction *fs_toggle_action;
1994 mgr = modest_runtime_get_window_mgr ();
1995 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1997 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1999 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2000 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
2001 if (is_fullscreen != active)
2002 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
2010 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
2012 ModestWindowPrivate *parent_priv;
2013 GtkAction *fs_toggle_action;
2016 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2018 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
2019 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
2020 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
2024 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
2027 ModestMsgEditWindowPrivate *priv = NULL;
2028 const gchar *recipients;
2029 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2031 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2032 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2033 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field));
2034 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2035 gtk_widget_show (priv->cc_caption);
2037 gtk_widget_hide (priv->cc_caption);
2038 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2042 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2045 ModestMsgEditWindowPrivate *priv = NULL;
2046 const gchar *recipients;
2047 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2049 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2050 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2051 recipients = modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field));
2052 if ((show) || ((recipients != NULL) && (recipients[0] != '\0')))
2053 gtk_widget_show (priv->bcc_caption);
2055 gtk_widget_hide (priv->bcc_caption);
2056 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2060 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2061 ModestRecptEditor *editor)
2063 ModestMsgEditWindowPrivate *priv;
2065 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2066 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2067 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2069 if (editor == NULL) {
2070 GtkWidget *view_focus;
2071 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2073 /* This code should be kept in sync with ModestRecptEditor. The
2074 textview inside the recpt editor is the one that really gets the
2075 focus. As it's inside a scrolled window, and this one inside the
2076 hbox recpt editor inherits from, we'll need to go up in the
2077 hierarchy to know if the text view is part of the recpt editor
2078 or if it's a different text entry */
2080 if (gtk_widget_get_parent (view_focus)) {
2081 GtkWidget *first_parent;
2083 first_parent = gtk_widget_get_parent (view_focus);
2084 if (gtk_widget_get_parent (first_parent) &&
2085 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2086 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2091 editor = MODEST_RECPT_EDITOR (priv->to_field);
2095 modest_address_book_select_addresses (editor);
2100 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2102 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2104 modest_msg_edit_window_open_addressbook (window, NULL);
2108 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2109 gboolean show_toolbar)
2111 ModestWindowPrivate *parent_priv;
2113 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2114 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2116 /* FIXME: we can not just use the code of
2117 modest_msg_edit_window_setup_toolbar because it has a
2118 mixture of both initialization and creation code. */
2121 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2123 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2127 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2128 TnyHeaderFlags priority_flags)
2130 ModestMsgEditWindowPrivate *priv;
2131 ModestWindowPrivate *parent_priv;
2133 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2135 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2136 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2137 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2139 if (priv->priority_flags != priority_flags) {
2140 GtkAction *priority_action = NULL;
2142 priv->priority_flags = priority_flags;
2144 switch (priority_flags) {
2145 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2146 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2147 gtk_widget_show (priv->priority_icon);
2148 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2149 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2151 case TNY_HEADER_FLAG_LOW_PRIORITY:
2152 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2153 gtk_widget_show (priv->priority_icon);
2154 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2155 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2158 gtk_widget_hide (priv->priority_icon);
2159 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2160 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2163 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2164 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2169 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2172 ModestMsgEditWindowPrivate *priv;
2173 ModestWindowPrivate *parent_priv;
2174 gint current_format;
2176 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2178 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2179 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2181 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2182 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2184 if (current_format != file_format) {
2185 switch (file_format) {
2186 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2187 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2189 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2193 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2194 response = gtk_dialog_run (GTK_DIALOG (dialog));
2195 gtk_widget_destroy (dialog);
2196 if (response == GTK_RESPONSE_OK) {
2197 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2199 GtkToggleAction *action = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu"));
2200 toggle_action_set_active_block_notify (action, TRUE);
2205 update_dimmed (window);
2210 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2213 ModestMsgEditWindowPrivate *priv;
2214 WPTextBufferFormat oldfmt, fmt;
2215 gint old_position = 0;
2219 GdkColor *color = NULL;
2220 gboolean bold, bold_set, italic, italic_set;
2221 gboolean underline, underline_set;
2222 gboolean strikethrough, strikethrough_set;
2223 gboolean position_set;
2224 gboolean font_size_set, font_set, color_set;
2227 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2228 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2230 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2232 /* First we get the currently selected font information */
2233 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2234 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2236 switch (oldfmt.text_position) {
2237 case TEXT_POSITION_NORMAL:
2240 case TEXT_POSITION_SUPERSCRIPT:
2248 g_object_set (G_OBJECT (dialog),
2249 "bold", oldfmt.bold != FALSE,
2250 "bold-set", !oldfmt.cs.bold,
2251 "underline", oldfmt.underline != FALSE,
2252 "underline-set", !oldfmt.cs.underline,
2253 "italic", oldfmt.italic != FALSE,
2254 "italic-set", !oldfmt.cs.italic,
2255 "strikethrough", oldfmt.strikethrough != FALSE,
2256 "strikethrough-set", !oldfmt.cs.strikethrough,
2257 "color", &oldfmt.color,
2258 "color-set", !oldfmt.cs.color,
2259 "size", wp_font_size[oldfmt.font_size],
2260 "size-set", !oldfmt.cs.font_size,
2261 "position", old_position,
2262 "position-set", !oldfmt.cs.text_position,
2263 "family", wp_get_font_name (oldfmt.font),
2264 "family-set", !oldfmt.cs.font,
2267 gtk_widget_show_all (dialog);
2268 response = gtk_dialog_run (GTK_DIALOG (dialog));
2269 if (response == GTK_RESPONSE_OK) {
2271 g_object_get( dialog,
2273 "bold-set", &bold_set,
2274 "underline", &underline,
2275 "underline-set", &underline_set,
2277 "italic-set", &italic_set,
2278 "strikethrough", &strikethrough,
2279 "strikethrough-set", &strikethrough_set,
2281 "color-set", &color_set,
2283 "size-set", &font_size_set,
2284 "family", &font_name,
2285 "family-set", &font_set,
2286 "position", &position,
2287 "position-set", &position_set,
2292 if (response == GTK_RESPONSE_OK) {
2293 memset(&fmt, 0, sizeof(fmt));
2299 fmt.italic = italic;
2300 fmt.cs.italic = TRUE;
2302 if (underline_set) {
2303 fmt.underline = underline;
2304 fmt.cs.underline = TRUE;
2306 if (strikethrough_set) {
2307 fmt.strikethrough = strikethrough;
2308 fmt.cs.strikethrough = TRUE;
2313 ? TEXT_POSITION_NORMAL
2314 : ( ( position == 1 )
2315 ? TEXT_POSITION_SUPERSCRIPT
2316 : TEXT_POSITION_SUBSCRIPT );
2317 fmt.cs.text_position = TRUE;
2321 fmt.cs.color = TRUE;
2324 fmt.font = wp_get_font_index(font_name,
2329 if (font_size_set) {
2330 fmt.font_size = wp_get_font_size_index(
2331 font_size, DEFAULT_FONT_SIZE);
2332 fmt.cs.font_size = TRUE;
2334 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2336 gtk_widget_destroy (dialog);
2338 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2342 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2344 ModestMsgEditWindowPrivate *priv;
2346 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2347 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2349 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2351 update_dimmed (window);
2356 modest_msg_edit_window_redo (ModestMsgEditWindow *window)
2358 ModestMsgEditWindowPrivate *priv;
2360 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2361 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2363 wp_text_buffer_redo (WP_TEXT_BUFFER (priv->text_buffer));
2365 update_dimmed (window);
2370 update_dimmed (ModestMsgEditWindow *window)
2372 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2373 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2377 gboolean editor_focused;
2379 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2380 editor_focused = gtk_widget_is_focus (priv->msg_body);
2382 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2383 gtk_action_set_sensitive (action, rich_text && editor_focused);
2384 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2385 gtk_action_set_sensitive (action, rich_text && editor_focused);
2386 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2387 gtk_action_set_sensitive (action, rich_text && editor_focused);
2388 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2389 gtk_action_set_sensitive (action, rich_text && editor_focused);
2390 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2391 gtk_action_set_sensitive (action, rich_text && editor_focused);
2392 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2393 gtk_action_set_sensitive (action, rich_text && editor_focused);
2394 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2395 gtk_action_set_sensitive (action, rich_text && editor_focused);
2396 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2397 gtk_action_set_sensitive (action, rich_text && editor_focused);
2398 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2399 gtk_action_set_sensitive (action, rich_text && editor_focused);
2400 widget = priv->font_color_button;
2401 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2402 widget = priv->font_size_toolitem;
2403 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2404 widget = priv->font_face_toolitem;
2405 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2409 setup_insensitive_handlers (ModestMsgEditWindow *window)
2411 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2412 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2415 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2416 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2417 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2418 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2419 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2420 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2421 widget = priv->font_color_button;
2422 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2423 widget = priv->font_size_toolitem;
2424 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2425 widget = priv->font_face_toolitem;
2426 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2431 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2433 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2436 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2437 gtk_action_set_sensitive (action, can_undo);
2441 text_buffer_can_redo (GtkTextBuffer *buffer, gboolean can_redo, ModestMsgEditWindow *window)
2443 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2446 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/RedoMenu");
2447 gtk_action_set_sensitive (action, can_redo);
2451 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2454 GtkTextIter match_start, match_end;
2456 if (image_id == NULL)
2459 gtk_text_buffer_get_start_iter (buffer, &iter);
2461 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2462 GSList *tags = gtk_text_iter_get_tags (&match_start);
2464 for (node = tags; node != NULL; node = g_slist_next (node)) {
2465 GtkTextTag *tag = (GtkTextTag *) node->data;
2466 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2467 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2468 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2470 offset = gtk_text_iter_get_offset (&match_start);
2471 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2472 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2476 gtk_text_iter_forward_char (&iter);
2481 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2483 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2484 GtkTextIter real_start, real_end;
2485 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2487 if (gtk_text_iter_compare (start, end) > 0) {
2491 real_start = *start;
2495 GSList *tags = gtk_text_iter_get_tags (&real_start);
2497 for (node = tags; node != NULL; node = g_slist_next (node)) {
2498 GtkTextTag *tag = (GtkTextTag *) node->data;
2499 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2500 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2502 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2504 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2507 } while (gtk_text_iter_forward_char (&real_start)&&
2508 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2512 msg_body_focus (GtkWidget *focus,
2513 GdkEventFocus *event,
2517 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2522 recpt_field_changed (GtkTextBuffer *buffer,
2523 ModestMsgEditWindow *editor)
2525 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2526 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2527 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2528 gboolean dim = FALSE;
2531 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2532 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2533 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2535 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2536 gtk_text_buffer_get_char_count (cc_buffer) +
2537 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2539 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2540 gtk_action_set_sensitive (action, !dim);
2541 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2542 gtk_action_set_sensitive (action, !dim);
2546 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2548 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2552 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2554 gboolean rich_text, editor_focused;
2556 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2557 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2558 editor_focused = gtk_widget_is_focus (priv->msg_body);
2561 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2562 else if (!editor_focused)
2563 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2567 reset_modified (ModestMsgEditWindow *editor)
2569 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2570 GtkTextBuffer *buffer;
2572 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2573 gtk_text_buffer_set_modified (buffer, FALSE);
2574 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2575 gtk_text_buffer_set_modified (buffer, FALSE);
2576 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2577 gtk_text_buffer_set_modified (buffer, FALSE);
2578 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2582 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2584 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2585 GtkTextBuffer *buffer;
2587 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2588 if (gtk_text_buffer_get_modified (buffer))
2590 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2591 if (gtk_text_buffer_get_modified (buffer))
2593 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2594 if (gtk_text_buffer_get_modified (buffer))
2596 if (gtk_text_buffer_get_modified (priv->text_buffer))
2603 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2605 ModestMsgEditWindowPrivate *priv = NULL;
2607 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2608 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2610 /* check if there's no recipient added */
2611 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2612 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2613 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2614 /* no recipient contents, then select contacts */
2615 modest_msg_edit_window_open_addressbook (window, NULL);
2619 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2621 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2623 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2626 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2633 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2634 ModestMsgEditWindow *window)
2636 modest_msg_edit_window_attach_file (window);
2640 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2642 ModestMsgEditWindow *window)
2644 ModestWindowPrivate *parent_priv;
2645 ModestMsgEditWindowPrivate *priv;
2647 gboolean has_selection;
2649 GList *selected_attachments = NULL;
2650 gint n_att_selected = 0;
2652 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2653 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2654 has_selection = gtk_clipboard_wait_for_targets (clipboard, NULL, NULL);
2655 focused = gtk_window_get_focus (GTK_WINDOW (window));
2657 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2658 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2659 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2660 gtk_action_set_sensitive (action, (has_selection) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2662 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2663 n_att_selected = g_list_length (selected_attachments);
2664 g_list_free (selected_attachments);
2666 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2667 gtk_action_set_sensitive (action, n_att_selected == 1);
2669 update_paste_dimming (window);
2673 update_window_title (ModestMsgEditWindow *window)
2675 ModestMsgEditWindowPrivate *priv = NULL;
2676 const gchar *subject;
2678 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2679 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2680 if (subject == NULL || subject[0] == '\0')
2681 subject = _("mail_va_new_email");
2683 gtk_window_set_title (GTK_WINDOW (window), subject);
2688 subject_field_changed (GtkEditable *editable,
2689 ModestMsgEditWindow *window)
2691 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2692 update_window_title (window);
2693 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2697 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2700 ModestMsgEditWindowPrivate *priv = NULL;
2702 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2703 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2705 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2707 gtk_widget_show_all (priv->find_toolbar);
2708 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2710 gtk_widget_hide_all (priv->find_toolbar);
2711 gtk_widget_grab_focus (priv->msg_body);
2717 gtk_text_iter_forward_search_insensitive (const GtkTextIter *iter,
2719 GtkTextIter *match_start,
2720 GtkTextIter *match_end)
2722 GtkTextIter end_iter;
2723 gchar *str_casefold;
2726 gchar *range_casefold;
2729 gboolean result = FALSE;
2736 gtk_text_iter_forward_to_end (&end_iter);
2738 str_casefold = g_utf8_casefold (str, -1);
2739 str_chars_n = strlen (str);
2741 range_text = gtk_text_iter_get_visible_text (iter, &end_iter);
2742 range_casefold = g_utf8_casefold (range_text, -1);
2743 range_chars_n = strlen (range_casefold);
2745 if (range_chars_n < str_chars_n) {
2746 g_free (str_casefold);
2747 g_free (range_text);
2748 g_free (range_casefold);
2752 for (offset = 0; offset <= range_chars_n - str_chars_n; offset++) {
2753 gchar *range_subtext = g_strndup (range_casefold + offset, str_chars_n);
2754 if (!g_utf8_collate (range_subtext, str_casefold)) {
2755 gchar *found_text = g_strndup (range_text + offset, str_chars_n);
2757 gtk_text_iter_forward_search (iter, found_text, GTK_TEXT_SEARCH_VISIBLE_ONLY|GTK_TEXT_SEARCH_TEXT_ONLY,
2758 match_start, match_end, NULL);
2759 g_free (found_text);
2761 g_free (range_subtext);
2765 g_free (str_casefold);
2766 g_free (range_text);
2767 g_free (range_casefold);
2774 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2775 ModestMsgEditWindow *window)
2777 gchar *current_search = NULL;
2778 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2780 GtkTextIter selection_start, selection_end;
2781 GtkTextIter match_start, match_end;
2782 gboolean continue_search = FALSE;
2784 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2785 if ((current_search == NULL) || (strcmp (current_search, "") == 0)) {
2786 g_free (current_search);
2787 g_free (priv->last_search);
2788 priv->last_search = NULL;
2789 /* Information banner about empty search */
2790 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-common-strings", "ecdg_ib_find_rep_enter_text"));
2794 if ((priv->last_search != NULL)&&(!strcmp (current_search, priv->last_search))) {
2795 continue_search = TRUE;
2797 g_free (priv->last_search);
2798 priv->last_search = g_strdup (current_search);
2801 if (continue_search) {
2802 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2803 result = gtk_text_iter_forward_search_insensitive (&selection_end, current_search,
2804 &match_start, &match_end);
2806 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_search_complete"));
2808 GtkTextIter buffer_start;
2809 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2810 result = gtk_text_iter_forward_search_insensitive (&buffer_start, current_search,
2811 &match_start, &match_end);
2813 hildon_banner_show_information (NULL, NULL, dgettext ("hildon-libs", "ckct_ib_find_no_matches"));
2816 /* Mark as selected the string found in search */
2818 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2819 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2821 g_free (priv->last_search);
2822 priv->last_search = NULL;
2824 g_free (current_search);
2828 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2829 ModestMsgEditWindow *window)
2831 GtkToggleAction *toggle;
2832 ModestWindowPrivate *parent_priv;
2833 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2835 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2836 gtk_toggle_action_set_active (toggle, FALSE);
2841 update_paste_dimming (ModestMsgEditWindow *window)
2843 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2844 GtkAction *action = NULL;
2845 GtkClipboard *clipboard = NULL;
2849 focused = gtk_window_get_focus (GTK_WINDOW (window));
2851 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2852 active = gtk_clipboard_wait_is_text_available (clipboard);
2855 if (MODEST_IS_ATTACHMENTS_VIEW (focused))
2859 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2860 gtk_action_set_sensitive (action, active);
2866 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2868 ModestMsgEditWindow *window)
2870 update_paste_dimming (window);
2874 update_select_all_dimming (ModestMsgEditWindow *window)
2877 gboolean dimmed = FALSE;
2879 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2881 focused = gtk_window_get_focus (GTK_WINDOW (window));
2882 if (GTK_IS_ENTRY (focused)) {
2883 const gchar *current_text;
2884 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2885 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2886 } else if (GTK_IS_TEXT_VIEW (focused)) {
2887 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2888 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2889 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2892 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2893 gtk_action_set_sensitive (action, !dimmed);
2897 update_zoom_dimming (ModestMsgEditWindow *window)
2900 gboolean dimmed = FALSE;
2902 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2904 focused = gtk_window_get_focus (GTK_WINDOW (window));
2905 dimmed = ! WP_IS_TEXT_VIEW (focused);
2906 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2907 gtk_action_set_sensitive (action, !dimmed);
2911 edit_menu_activated (GtkAction *action,
2914 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2916 update_select_all_dimming (window);
2919 view_menu_activated (GtkAction *action,
2922 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2924 update_zoom_dimming (window);
2928 modest_msg_edit_window_get_sent (ModestMsgEditWindow *window)
2930 ModestMsgEditWindowPrivate *priv;
2932 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2937 modest_msg_edit_window_set_sent (ModestMsgEditWindow *window,
2940 ModestMsgEditWindowPrivate *priv;
2942 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(window);
2948 modest_msg_edit_window_set_draft (ModestMsgEditWindow *window,
2951 ModestMsgEditWindowPrivate *priv;
2952 TnyHeader *header = NULL;
2954 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2955 g_return_if_fail ((draft == NULL)||(TNY_IS_MSG (draft)));
2957 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2958 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
2960 if (priv->draft_msg != NULL) {
2961 header = tny_msg_get_header (priv->draft_msg);
2962 if (TNY_IS_HEADER (header)) {
2963 modest_window_mgr_unregister_header (mgr, header);
2965 g_object_unref (priv->draft_msg);
2968 if (draft != NULL) {
2969 g_object_ref (draft);
2970 header = tny_msg_get_header (draft);
2971 if (TNY_IS_HEADER (header))
2972 modest_window_mgr_register_header (mgr, header);
2975 priv->draft_msg = draft;