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-address-book.h"
59 #include "modest-text-utils.h"
60 #include <tny-simple-list.h>
61 #include <wptextview.h>
62 #include <wptextbuffer.h>
63 #include "modest-scroll-area.h"
65 #include "modest-hildon-includes.h"
66 #ifdef MODEST_HAVE_HILDON0_WIDGETS
67 #include <hildon-widgets/hildon-color-chooser.h>
69 #include "widgets/modest-msg-edit-window-ui.h"
70 #ifdef MODEST_HAVE_HILDON0_WIDGETS
71 #include <libgnomevfs/gnome-vfs-mime-utils.h>
73 #include <libgnomevfs/gnome-vfs-mime.h>
75 #include "modest-maemo-utils.h"
78 #define DEFAULT_FONT_SIZE 3
79 #define DEFAULT_FONT 2
80 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
81 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
82 #define DEFAULT_MAIN_VBOX_SPACING 6
83 #define SUBJECT_MAX_LENGTH 1000
84 #define IMAGE_MAX_WIDTH 640
86 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
87 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
88 static void modest_msg_edit_window_finalize (GObject *obj);
90 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
91 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
92 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
93 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
94 static void remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
95 static void zoom_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_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
103 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
104 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
106 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
108 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
110 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
111 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
112 GdkEventWindowState *event,
114 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
115 ModestRecptEditor *editor);
116 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
117 ModestMsgEditWindow *window);
119 /* ModestWindow methods implementation */
120 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
121 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
122 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
123 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
124 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
125 gboolean show_toolbar);
126 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
128 ModestMsgEditWindow *window);
129 static void modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
131 ModestMsgEditWindow *window);
132 static void update_window_title (ModestMsgEditWindow *window);
133 static void update_dimmed (ModestMsgEditWindow *window);
134 static void update_paste_dimming (ModestMsgEditWindow *window);
135 static void update_select_all_dimming (ModestMsgEditWindow *window);
136 static void update_zoom_dimming (ModestMsgEditWindow *window);
139 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
140 ModestMsgEditWindow *window);
141 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
142 ModestMsgEditWindow *window);
143 static void edit_menu_activated (GtkAction *action,
145 static void view_menu_activated (GtkAction *action,
148 /* list my signals */
155 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
156 struct _ModestMsgEditWindowPrivate {
158 GtkWidget *header_box;
160 ModestPairList *from_field_protos;
161 GtkWidget *from_field;
165 GtkWidget *bcc_field;
166 GtkWidget *subject_field;
167 GtkWidget *attachments_view;
168 GtkWidget *priority_icon;
169 GtkWidget *add_attachment_button;
171 GtkWidget *cc_caption;
172 GtkWidget *bcc_caption;
173 GtkWidget *attachments_caption;
175 GtkTextBuffer *text_buffer;
177 GtkWidget *font_size_toolitem;
178 GtkWidget *font_face_toolitem;
179 GtkWidget *font_color_button;
180 GSList *font_items_group;
181 GtkWidget *font_tool_button_label;
182 GSList *size_items_group;
183 GtkWidget *size_tool_button_label;
185 GtkWidget *find_toolbar;
188 GtkWidget *scroll_area;
193 TnyHeaderFlags priority_flags;
197 gulong clipboard_change_handler_id;
198 gulong system_clipboard_change_handler_id;
203 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
204 MODEST_TYPE_MSG_EDIT_WINDOW, \
205 ModestMsgEditWindowPrivate))
207 static GtkWindowClass *parent_class = NULL;
209 /* uncomment the following if you have defined any signals */
210 /* static guint signals[LAST_SIGNAL] = {0}; */
213 modest_msg_edit_window_get_type (void)
215 static GType my_type = 0;
217 static const GTypeInfo my_info = {
218 sizeof(ModestMsgEditWindowClass),
219 NULL, /* base init */
220 NULL, /* base finalize */
221 (GClassInitFunc) modest_msg_edit_window_class_init,
222 NULL, /* class finalize */
223 NULL, /* class data */
224 sizeof(ModestMsgEditWindow),
226 (GInstanceInitFunc) modest_msg_edit_window_init,
229 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
230 "ModestMsgEditWindow",
233 wp_text_buffer_library_init ();
239 save_state (ModestWindow *self)
241 modest_widget_memory_save (modest_runtime_get_conf(),
242 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
247 restore_settings (ModestMsgEditWindow *self)
249 modest_widget_memory_restore (modest_runtime_get_conf(),
250 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
255 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
257 GObjectClass *gobject_class;
258 ModestWindowClass *modest_window_class;
259 gobject_class = (GObjectClass*) klass;
260 modest_window_class = (ModestWindowClass*) klass;
262 parent_class = g_type_class_peek_parent (klass);
263 gobject_class->finalize = modest_msg_edit_window_finalize;
265 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
266 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
267 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
268 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
269 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
271 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
273 modest_window_class->save_state_func = save_state;
277 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
279 ModestMsgEditWindowPrivate *priv;
280 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
282 priv->msg_body = NULL;
283 priv->from_field = NULL;
284 priv->to_field = NULL;
285 priv->cc_field = NULL;
286 priv->bcc_field = NULL;
287 priv->subject_field = NULL;
288 priv->attachments = NULL;
290 priv->zoom_level = 1.0;
292 priv->cc_caption = NULL;
293 priv->bcc_caption = NULL;
295 priv->priority_flags = 0;
297 priv->find_toolbar = NULL;
299 priv->draft_msg = NULL;
300 priv->clipboard_change_handler_id = 0;
301 priv->system_clipboard_change_handler_id = 0;
305 /* FIXME: this is a dup from the one in gtk/ */
308 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
310 static ModestPairList*
311 get_transports (void)
313 GSList *transports = NULL;
315 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
316 GSList *accounts = modest_account_mgr_account_names (account_mgr,
317 TRUE /* only enabled accounts. */);
319 GSList *cursor = accounts;
321 gchar *account_name = cursor->data;
322 gchar *from_string = NULL;
324 from_string = modest_account_mgr_get_from_string (account_mgr,
328 if (from_string && account_name) {
329 gchar *name = account_name;
330 ModestPair *pair = modest_pair_new ((gpointer) name,
331 (gpointer) from_string , TRUE);
332 transports = g_slist_prepend (transports, pair);
335 cursor = cursor->next;
337 g_slist_free (accounts); /* only free the accounts, not the elements,
338 * because they are used in the pairlist */
344 init_window (ModestMsgEditWindow *obj)
346 GtkWidget *from_caption, *to_caption, *subject_caption;
347 GtkWidget *main_vbox;
348 ModestMsgEditWindowPrivate *priv;
350 GtkSizeGroup *size_group;
352 GtkWidget *subject_box;
353 GtkWidget *attachment_icon;
354 GtkWidget *window_box;
356 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
358 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
360 /* Note: This ModestPairList* must exist for as long as the combo
361 * that uses it, because the ModestComboBox uses the ID opaquely,
362 * so it can't know how to manage its memory. */
363 priv->from_field_protos = get_transports ();
365 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
367 priv->to_field = modest_recpt_editor_new ();
368 priv->cc_field = modest_recpt_editor_new ();
369 priv->bcc_field = modest_recpt_editor_new ();
370 subject_box = gtk_hbox_new (FALSE, 0);
371 priv->priority_icon = gtk_image_new ();
372 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
373 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
374 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
375 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
376 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
377 priv->add_attachment_button = gtk_button_new ();
378 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
379 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
380 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
381 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
382 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
383 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
384 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
385 priv->attachments_view = modest_attachments_view_new (NULL);
387 priv->header_box = gtk_vbox_new (FALSE, 0);
389 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
390 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
391 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
392 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
393 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
394 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
395 g_object_unref (size_group);
397 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
398 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
399 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
400 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
401 gtk_size_group_add_widget (size_group, priv->subject_field);
402 gtk_size_group_add_widget (size_group, priv->attachments_view);
403 g_object_unref (size_group);
405 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
406 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
407 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
408 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
409 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
410 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
411 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
414 priv->msg_body = wp_text_view_new ();
415 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
416 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
417 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
418 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
419 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
420 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
422 priv->find_toolbar = hildon_find_toolbar_new (NULL);
423 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
425 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
426 G_CALLBACK (text_buffer_refresh_attributes), obj);
427 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
428 G_CALLBACK (text_buffer_delete_range), obj);
429 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
430 G_CALLBACK (text_buffer_can_undo), obj);
431 g_signal_connect (G_OBJECT (obj), "window-state-event",
432 G_CALLBACK (modest_msg_edit_window_window_state_event),
434 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
435 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
436 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
437 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
438 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
439 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
441 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
442 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
444 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
445 G_CALLBACK (msg_body_focus), obj);
446 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
447 G_CALLBACK (msg_body_focus), obj);
448 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
449 "changed", G_CALLBACK (recpt_field_changed), obj);
450 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
451 "changed", G_CALLBACK (recpt_field_changed), obj);
452 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
453 "changed", G_CALLBACK (recpt_field_changed), obj);
454 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
455 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
457 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
458 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
460 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
461 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
462 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
464 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
466 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
467 frame = gtk_frame_new (NULL);
468 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
470 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
471 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
472 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
474 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
475 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
476 gtk_widget_hide (priv->cc_caption);
478 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
479 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
480 gtk_widget_hide (priv->bcc_caption);
483 window_box = gtk_vbox_new (FALSE, 0);
484 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
485 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
486 gtk_container_add (GTK_CONTAINER(obj), window_box);
487 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
488 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
491 TODO: scroll_area was never instantiated.
492 Stop building without warnings-as-errors. murrayc.
493 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
494 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
497 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
498 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
499 priv->system_clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
500 G_CALLBACK (modest_msg_edit_window_system_clipboard_owner_change), obj);
506 modest_msg_edit_window_finalize (GObject *obj)
508 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
510 if (priv->clipboard_change_handler_id > 0) {
511 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
512 priv->clipboard_change_handler_id = 0;
515 if (priv->system_clipboard_change_handler_id > 0) {
516 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
517 priv->system_clipboard_change_handler_id);
518 priv->system_clipboard_change_handler_id = 0;
521 /* This had to stay alive for as long as the combobox that used it: */
522 modest_pair_list_free (priv->from_field_protos);
524 G_OBJECT_CLASS(parent_class)->finalize (obj);
528 menubar_to_menu (GtkUIManager *ui_manager)
530 GtkWidget *main_menu;
534 /* Create new main menu */
535 main_menu = gtk_menu_new();
537 /* Get the menubar from the UI manager */
538 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
540 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
544 menu = GTK_WIDGET (iter->data);
545 gtk_widget_reparent(menu, main_menu);
547 iter = g_list_next (iter);
554 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
557 const gchar *to, *cc, *bcc, *subject;
559 ModestMsgEditWindowPrivate *priv;
561 TnyHeaderFlags priority_flags;
563 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
564 g_return_if_fail (TNY_IS_MSG (msg));
566 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
568 header = tny_msg_get_header (msg);
569 to = tny_header_get_to (header);
570 cc = tny_header_get_cc (header);
571 bcc = tny_header_get_bcc (header);
572 subject = tny_header_get_subject (header);
573 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
576 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
578 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
580 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
582 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
583 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
586 update_window_title (self);
588 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
589 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
590 body = modest_tny_msg_get_body (msg, TRUE);
592 if ((body == NULL)||(body[0] == '\0')) {
594 body = modest_text_utils_convert_to_html ("");
596 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
597 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
600 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
603 /* Get the default format required from configuration */
604 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
605 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
608 /* Set the default focus depending on having already a To: field or not */
609 if ((!to)||(*to == '\0')) {
610 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
612 gtk_widget_grab_focus (priv->msg_body);
615 /* TODO: lower priority, select in the From: combo to the
616 value that comes from msg <- not sure, should it be
619 /* Add attachments to the view */
620 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
621 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
622 if (priv->attachments == NULL) {
623 gtk_widget_hide (priv->attachments_caption);
625 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
626 gtk_widget_show_all (priv->attachments_caption);
629 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
630 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
632 reset_modified (self);
634 update_dimmed (self);
635 text_buffer_can_undo (priv->text_buffer, FALSE, self);
637 priv->draft_msg = msg;
641 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
644 GList *item_children, *node;
645 GtkWidget *bin_child;
647 bin_child = gtk_bin_get_child (GTK_BIN(item));
649 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
651 for (node = item_children; node != NULL; node = g_list_next (node)) {
652 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
653 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
656 g_list_free (item_children);
660 menu_tool_button_dont_expand (GtkMenuToolButton *item)
663 GList *item_children, *node;
665 box = gtk_bin_get_child (GTK_BIN (item));
666 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
667 item_children = gtk_container_get_children (GTK_CONTAINER (box));
669 for (node = item_children; node != NULL; node = g_list_next (node)) {
670 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
671 if (GTK_IS_TOGGLE_BUTTON (node->data))
672 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
673 else if (GTK_IS_BUTTON (node->data))
674 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
676 g_list_free (item_children);
681 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
683 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
684 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
685 GtkWidget *placeholder;
686 GtkWidget *tool_item;
691 GtkWidget *sizes_menu;
692 GtkWidget *fonts_menu;
693 GSList *radio_group = NULL;
698 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
699 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
701 /* should we hide the toolbar? */
702 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
703 gtk_widget_hide (parent_priv->toolbar);
705 /* Font color placeholder */
706 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
707 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
710 tool_item = GTK_WIDGET (gtk_tool_item_new ());
711 priv->font_color_button = hildon_color_button_new ();
712 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
713 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
714 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
715 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
716 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
717 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
718 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
720 /* Font size and face placeholder */
721 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
722 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
724 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
725 priv->size_tool_button_label = gtk_label_new (NULL);
726 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
727 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
728 size_text,"</span>", NULL);
729 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
731 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
732 sizes_menu = gtk_menu_new ();
733 priv->size_items_group = NULL;
735 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
736 GtkWidget *size_menu_item;
738 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
739 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
740 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
741 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
742 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
743 gtk_widget_show (size_menu_item);
745 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
749 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
750 GtkWidget *item = (GtkWidget *) node->data;
751 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
755 priv->size_items_group = g_slist_reverse (priv->size_items_group);
756 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
757 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
758 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
759 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
760 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
761 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
762 priv->font_size_toolitem = tool_item;
765 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
766 priv->font_tool_button_label = gtk_label_new (NULL);
767 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
768 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
770 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
771 fonts_menu = gtk_menu_new ();
772 priv->font_items_group = NULL;
774 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
775 GtkWidget *font_menu_item;
776 GtkWidget *child_label;
778 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
779 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
780 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
781 wp_get_font_name (font_index), "</span>", NULL);
782 gtk_label_set_markup (GTK_LABEL (child_label), markup);
785 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
786 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
787 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
788 gtk_widget_show (font_menu_item);
790 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
793 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
794 GtkWidget *item = (GtkWidget *) node->data;
795 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
798 priv->font_items_group = g_slist_reverse (priv->font_items_group);
799 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
800 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
801 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
802 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
803 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
804 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
805 priv->font_face_toolitem = tool_item;
807 /* Set expand and homogeneous for remaining items */
808 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
809 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
810 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
811 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
812 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
813 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
814 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
815 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
816 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
824 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
827 ModestWindowPrivate *parent_priv;
828 ModestMsgEditWindowPrivate *priv;
829 GtkActionGroup *action_group;
830 GError *error = NULL;
831 GdkPixbuf *window_icon = NULL;
834 gboolean prefer_formatted;
836 ModestPair *account_pair = NULL;
838 g_return_val_if_fail (msg, NULL);
839 g_return_val_if_fail (account_name, NULL);
841 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
843 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
844 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
846 parent_priv->ui_manager = gtk_ui_manager_new();
847 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
848 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
850 /* Add common actions */
851 gtk_action_group_add_actions (action_group,
852 modest_msg_edit_action_entries,
853 G_N_ELEMENTS (modest_msg_edit_action_entries),
855 gtk_action_group_add_toggle_actions (action_group,
856 modest_msg_edit_toggle_action_entries,
857 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
859 gtk_action_group_add_radio_actions (action_group,
860 modest_msg_edit_alignment_radio_action_entries,
861 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
863 G_CALLBACK (modest_ui_actions_on_change_justify),
865 gtk_action_group_add_radio_actions (action_group,
866 modest_msg_edit_zoom_action_entries,
867 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
869 G_CALLBACK (modest_ui_actions_on_change_zoom),
871 gtk_action_group_add_radio_actions (action_group,
872 modest_msg_edit_priority_action_entries,
873 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
875 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
877 gtk_action_group_add_radio_actions (action_group,
878 modest_msg_edit_file_format_action_entries,
879 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
880 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
881 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
883 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
884 g_object_unref (action_group);
886 /* Load the UI definition */
887 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
890 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
891 g_clear_error (&error);
894 /* Add accelerators */
895 gtk_window_add_accel_group (GTK_WINDOW (obj),
896 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
899 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
900 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
903 init_window (MODEST_MSG_EDIT_WINDOW(obj));
905 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
907 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
909 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
911 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
913 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
915 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
916 if (account_pair != NULL)
917 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
919 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
921 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
923 /* Set window icon */
924 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
925 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
927 /* Dim at start clipboard actions */
928 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
929 gtk_action_set_sensitive (action, FALSE);
930 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
931 gtk_action_set_sensitive (action, FALSE);
932 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
933 gtk_action_set_sensitive (action, FALSE);
935 /* Update select all */
936 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
937 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
938 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
939 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
940 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
942 /* set initial state of cc and bcc */
943 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
944 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
945 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
946 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
947 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
948 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
950 /* Setup the file format */
951 conf = modest_runtime_get_conf ();
952 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
954 g_clear_error (&error);
955 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
957 file_format = (prefer_formatted) ?
958 MODEST_FILE_FORMAT_FORMATTED_TEXT :
959 MODEST_FILE_FORMAT_PLAIN_TEXT;
960 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
962 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
964 return (ModestWindow*) obj;
968 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
970 GString **string_buffer = (GString **) user_data;
972 *string_buffer = g_string_append (*string_buffer, buffer);
978 * @result: A new string which should be freed with g_free().
981 get_formatted_data (ModestMsgEditWindow *edit_window)
983 ModestMsgEditWindowPrivate *priv;
984 GString *string_buffer = g_string_new ("");
986 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
988 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
990 return g_string_free (string_buffer, FALSE);
995 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
998 const gchar *account_name;
999 ModestMsgEditWindowPrivate *priv;
1001 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1003 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1005 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1006 g_return_val_if_fail (account_name, NULL);
1009 /* don't free these (except from) */
1010 data = g_slice_new0 (MsgData);
1011 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1013 data->account_name = g_strdup (account_name);
1014 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1015 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1016 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1017 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1018 if (priv->draft_msg) {
1019 data->draft_msg = g_object_ref (priv->draft_msg);
1021 data->draft_msg = NULL;
1024 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1026 gtk_text_buffer_get_bounds (buf, &b, &e);
1027 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1029 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1030 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1032 data->html_body = NULL;
1034 data->attachments = priv->attachments; /* TODO: copy and free ? */
1035 data->priority_flags = priv->priority_flags;
1040 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1042 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1045 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1053 g_free (data->subject);
1054 g_free (data->plain_body);
1055 g_free (data->html_body);
1056 if (data->draft_msg != NULL) {
1057 g_object_unref (data->draft_msg);
1058 data->draft_msg = NULL;
1060 g_free (data->account_name);
1062 /* TODO: Free data->attachments? */
1064 g_slice_free (MsgData, data);
1068 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1071 ModestMsgEditWindowPrivate *priv = NULL;
1072 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1074 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1076 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1078 return MODEST_MSG_EDIT_FORMAT_HTML;
1080 return MODEST_MSG_EDIT_FORMAT_TEXT;
1084 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1085 ModestMsgEditFormat format)
1087 ModestMsgEditWindowPrivate *priv;
1089 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1090 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1093 case MODEST_MSG_EDIT_FORMAT_HTML:
1094 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1096 case MODEST_MSG_EDIT_FORMAT_TEXT:
1097 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1100 g_return_if_reached ();
1104 ModestMsgEditFormatState *
1105 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1107 ModestMsgEditFormatState *format_state = NULL;
1108 ModestMsgEditWindowPrivate *priv;
1109 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1111 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1112 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1114 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1116 format_state = g_new0 (ModestMsgEditFormatState, 1);
1117 format_state->bold = buffer_format->bold&0x1;
1118 format_state->italics = buffer_format->italic&0x1;
1119 format_state->bullet = buffer_format->bullet&0x1;
1120 format_state->color = buffer_format->color;
1121 format_state->font_size = buffer_format->font_size;
1122 format_state->font_family = wp_get_font_name (buffer_format->font);
1123 format_state->justification = buffer_format->justification;
1124 g_free (buffer_format);
1126 return format_state;
1131 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1132 const ModestMsgEditFormatState *format_state)
1134 ModestMsgEditWindowPrivate *priv;
1135 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1136 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1137 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1138 g_return_if_fail (format_state != NULL);
1140 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1141 gtk_widget_grab_focus (priv->msg_body);
1142 buffer_format->bold = (format_state->bold != FALSE);
1143 buffer_format->italic = (format_state->italics != FALSE);
1144 buffer_format->color = format_state->color;
1145 buffer_format->font_size = format_state->font_size;
1146 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1147 buffer_format->justification = format_state->justification;
1148 buffer_format->bullet = format_state->bullet;
1150 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1152 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1153 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1154 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1155 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1156 buffer_format->cs.font = (buffer_format->font != current_format->font);
1157 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1158 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1160 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1161 if (buffer_format->cs.bold) {
1162 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1164 if (buffer_format->cs.italic) {
1165 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1167 if (buffer_format->cs.color) {
1168 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1170 if (buffer_format->cs.font_size) {
1171 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1173 if (buffer_format->cs.justification) {
1174 switch (buffer_format->justification) {
1175 case GTK_JUSTIFY_LEFT:
1176 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1178 case GTK_JUSTIFY_CENTER:
1179 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1181 case GTK_JUSTIFY_RIGHT:
1182 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1189 if (buffer_format->cs.font) {
1190 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1192 if (buffer_format->cs.bullet) {
1193 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1195 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1196 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1198 g_free (current_format);
1203 toggle_action_set_active_block_notify (GtkToggleAction *action,
1206 GSList *proxies = NULL;
1208 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1209 proxies != NULL; proxies = g_slist_next (proxies)) {
1210 GtkWidget *widget = (GtkWidget *) proxies->data;
1211 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1214 gtk_toggle_action_set_active (action, value);
1216 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1217 proxies != NULL; proxies = g_slist_next (proxies)) {
1218 GtkWidget *widget = (GtkWidget *) proxies->data;
1219 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1224 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1226 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1228 ModestWindowPrivate *parent_priv;
1229 ModestMsgEditWindowPrivate *priv;
1230 GtkWidget *new_size_menuitem;
1231 GtkWidget *new_font_menuitem;
1233 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1234 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1236 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1237 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1238 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1239 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1241 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1242 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1243 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1246 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1248 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1249 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1251 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1252 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1254 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1255 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1257 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1258 G_CALLBACK (modest_msg_edit_window_color_button_change),
1260 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1261 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1262 G_CALLBACK (modest_msg_edit_window_color_button_change),
1265 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1266 buffer_format->font_size))->data);
1267 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1271 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1272 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1273 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1275 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1276 G_CALLBACK (modest_msg_edit_window_size_change),
1278 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1279 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1280 G_CALLBACK (modest_msg_edit_window_size_change),
1284 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1285 buffer_format->font))->data);
1286 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1290 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1291 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1292 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1294 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1295 G_CALLBACK (modest_msg_edit_window_font_change),
1297 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1298 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1299 G_CALLBACK (modest_msg_edit_window_font_change),
1303 g_free (buffer_format);
1309 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1312 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1313 ModestMsgEditWindowPrivate *priv;
1314 GtkWidget *dialog = NULL;
1316 const GdkColor *new_color = NULL;
1318 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1319 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1321 #ifdef MODEST_HILDON_VERSION_0
1322 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1323 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1325 dialog = hildon_color_chooser_new ();
1326 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1327 #endif /*MODEST_HILDON_VERSION_0*/
1328 g_free (buffer_format);
1330 response = gtk_dialog_run (GTK_DIALOG (dialog));
1332 case GTK_RESPONSE_OK: {
1333 #ifdef MODEST_HILDON_VERSION_0
1334 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1337 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1339 #endif /*MODEST_HILDON_VERSION_0*/
1346 gtk_widget_destroy (dialog);
1348 if (new_color != NULL)
1349 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1354 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1357 ModestMsgEditWindowPrivate *priv;
1358 GtkWidget *dialog = NULL;
1360 GdkColor *old_color = NULL;
1361 const GdkColor *new_color = NULL;
1363 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1364 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1366 #ifdef MODEST_HILDON_VERSION_0
1367 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1368 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1370 dialog = hildon_color_chooser_new ();
1371 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1372 #endif /*MODEST_HILDON_VERSION_9*/
1374 response = gtk_dialog_run (GTK_DIALOG (dialog));
1376 case GTK_RESPONSE_OK: {
1377 #ifdef MODEST_HILDON_VERSION_0
1378 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1381 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1383 #endif /*MODEST_HILDON_VERSION_0*/
1389 gtk_widget_destroy (dialog);
1391 if (new_color != NULL)
1392 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1398 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1401 ModestMsgEditWindowPrivate *priv;
1402 GtkWidget *dialog = NULL;
1404 GSList *uris = NULL;
1405 GSList *uri_node = NULL;
1407 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1409 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1410 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1411 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1413 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1415 response = gtk_dialog_run (GTK_DIALOG (dialog));
1417 case GTK_RESPONSE_OK:
1418 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1423 gtk_widget_destroy (dialog);
1425 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1427 GnomeVFSHandle *handle = NULL;
1428 GnomeVFSResult result;
1429 GtkTextIter position;
1430 GtkTextMark *insert_mark;
1432 uri = (const gchar *) uri_node->data;
1433 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1434 if (result == GNOME_VFS_OK) {
1435 GdkPixbufLoader *loader;
1437 GnomeVFSFileInfo info;
1438 gchar *filename, *basename;
1439 TnyMimePart *mime_part;
1442 const gchar *mime_type = NULL;
1444 filename = g_filename_from_uri (uri, NULL, NULL);
1445 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1447 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1449 mime_part = tny_platform_factory_new_mime_part
1450 (modest_runtime_get_platform_factory ());
1451 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1453 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1455 content_id = g_strdup_printf ("%d", priv->last_cid);
1456 tny_mime_part_set_content_id (mime_part, content_id);
1457 g_free (content_id);
1460 basename = g_path_get_basename (filename);
1461 tny_mime_part_set_filename (mime_part, basename);
1464 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1465 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1467 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1468 gtk_widget_show_all (priv->attachments_caption);
1469 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1472 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1473 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1474 char read_buffer[128];
1476 readed = tny_stream_read (TNY_STREAM (stream), read_buffer, 128);
1477 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1480 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1481 g_object_ref (pixbuf);
1482 gdk_pixbuf_loader_close (loader, NULL);
1483 g_object_unref (loader);
1485 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1486 GdkPixbuf *new_pixbuf;
1488 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1489 gdk_pixbuf_get_width (pixbuf);
1490 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1491 g_object_unref (pixbuf);
1492 pixbuf = new_pixbuf;
1495 if (pixbuf != NULL) {
1496 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1497 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1498 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1507 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1510 ModestMsgEditWindowPrivate *priv;
1511 GtkWidget *dialog = NULL;
1513 GSList *uris = NULL;
1516 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1518 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1519 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1521 response = gtk_dialog_run (GTK_DIALOG (dialog));
1523 case GTK_RESPONSE_OK:
1524 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1529 gtk_widget_destroy (dialog);
1531 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1533 GnomeVFSHandle *handle = NULL;
1534 GnomeVFSResult result;
1536 uri = (const gchar *) uri_node->data;
1537 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1538 if (result == GNOME_VFS_OK) {
1539 TnyMimePart *mime_part;
1541 const gchar *mime_type = NULL;
1545 GnomeVFSFileInfo info;
1547 filename = g_filename_from_uri (uri, NULL, NULL);
1549 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1550 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1551 mime_part = tny_platform_factory_new_mime_part
1552 (modest_runtime_get_platform_factory ());
1553 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1555 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1557 content_id = g_strdup_printf ("%d", priv->last_cid);
1558 tny_mime_part_set_content_id (mime_part, content_id);
1559 g_free (content_id);
1562 basename = g_path_get_basename (filename);
1563 tny_mime_part_set_filename (mime_part, basename);
1566 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1567 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1569 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1570 gtk_widget_show_all (priv->attachments_caption);
1571 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1576 g_slist_foreach (uris, (GFunc) g_free, NULL);
1577 g_slist_free (uris);
1581 modest_msg_edit_window_attach_file_noninteractive (
1582 ModestMsgEditWindow *window,
1583 const gchar *file_uri)
1586 ModestMsgEditWindowPrivate *priv;
1588 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1593 /* TODO: We should probably try to use only the URI,
1594 * instead of using a filename.
1596 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1598 g_warning("%s: g_filename_from_uri(%s) failed.\n", __FUNCTION__, file_uri);
1601 file_id = g_open (filename, O_RDONLY, 0);
1602 if (file_id != -1) {
1603 TnyMimePart *mime_part;
1605 const gchar *mime_type;
1608 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1609 mime_type = gnome_vfs_get_mime_type(filename);
1611 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1613 mime_part = tny_platform_factory_new_mime_part
1614 (modest_runtime_get_platform_factory ());
1615 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1617 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1619 content_id = g_strdup_printf ("%d", priv->last_cid);
1620 tny_mime_part_set_content_id (mime_part, content_id);
1621 g_free (content_id);
1624 basename = g_path_get_basename (filename);
1625 tny_mime_part_set_filename (mime_part, basename);
1628 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1629 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1631 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1632 gtk_widget_show_all (priv->attachments_caption);
1633 } else if (file_id == -1) {
1635 g_warning("file to be attached does not exist: %s", filename);
1643 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1646 ModestMsgEditWindowPrivate *priv;
1647 gboolean clean_list = FALSE;
1649 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1650 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1652 if (att_list == NULL) {
1653 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1657 if (att_list == NULL) {
1658 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1660 GtkWidget *confirmation_dialog = NULL;
1661 gboolean dialog_response;
1663 gchar *message = NULL;
1664 const gchar *filename = NULL;
1666 if (att_list->next == NULL) {
1667 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1671 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1672 att_list->next == NULL), filename);
1673 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1675 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1676 gtk_widget_destroy (confirmation_dialog);
1677 if (!dialog_response) {
1679 g_list_free (att_list);
1682 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1684 for (node = att_list; node != NULL; node = g_list_next (node)) {
1685 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1686 const gchar *att_id;
1687 priv->attachments = g_list_remove (priv->attachments, mime_part);
1689 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1691 if (priv->attachments == NULL)
1692 gtk_widget_hide (priv->attachments_caption);
1693 att_id = tny_mime_part_get_content_id (mime_part);
1695 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1697 g_object_unref (mime_part);
1698 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1703 g_list_free (att_list);
1707 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1710 ModestMsgEditWindowPrivate *priv;
1711 GdkColor *new_color;
1712 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1714 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1715 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1718 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1720 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1722 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1724 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1729 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1732 ModestMsgEditWindowPrivate *priv;
1733 gint new_size_index;
1734 ModestMsgEditWindow *window;
1737 window = MODEST_MSG_EDIT_WINDOW (userdata);
1738 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1739 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1741 if (gtk_check_menu_item_get_active (menu_item)) {
1743 WPTextBufferFormat format;
1745 memset (&format, 0, sizeof (format));
1746 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1748 label = gtk_bin_get_child (GTK_BIN (menu_item));
1750 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1751 format.cs.font_size = TRUE;
1752 format.cs.text_position = TRUE;
1753 format.cs.font = TRUE;
1754 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1755 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1757 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1758 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1759 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1761 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1762 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1763 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1769 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1772 ModestMsgEditWindowPrivate *priv;
1773 gint new_font_index;
1774 ModestMsgEditWindow *window;
1777 window = MODEST_MSG_EDIT_WINDOW (userdata);
1778 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1779 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1781 if (gtk_check_menu_item_get_active (menu_item)) {
1784 label = gtk_bin_get_child (GTK_BIN (menu_item));
1786 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1788 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1789 (gpointer) new_font_index))
1790 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1792 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1793 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1794 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1800 modest_msg_edit_window_set_zoom (ModestWindow *window,
1803 ModestMsgEditWindowPrivate *priv;
1804 ModestWindowPrivate *parent_priv;
1805 GtkRadioAction *zoom_radio_action;
1807 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1809 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1810 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1811 priv->zoom_level = zoom;
1812 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1814 /* Zoom level menu options should be updated with the current zoom level */
1815 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1816 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1817 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1818 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1819 /* FIXME: Not availible before Gtk 2.10 */
1821 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1826 modest_msg_edit_window_get_zoom (ModestWindow *window)
1828 ModestMsgEditWindowPrivate *priv;
1830 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1832 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1833 return priv->zoom_level;
1837 zoom_allowed (ModestMsgEditWindow *window)
1841 focus = gtk_window_get_focus (GTK_WINDOW (window));
1842 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1846 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1848 ModestWindowPrivate *parent_priv;
1849 GtkRadioAction *zoom_radio_action;
1850 GSList *group, *node;
1852 /* First we check if the text view is focused. If not, zooming is not allowed */
1853 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1854 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1858 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1859 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1860 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1862 group = gtk_radio_action_get_group (zoom_radio_action);
1864 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1865 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1869 for (node = group; node != NULL; node = g_slist_next (node)) {
1870 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1871 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1879 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1881 ModestWindowPrivate *parent_priv;
1882 GtkRadioAction *zoom_radio_action;
1883 GSList *group, *node;
1885 /* First we check if the text view is focused. If not, zooming is not allowed */
1886 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1887 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1891 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1892 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1893 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1895 group = gtk_radio_action_get_group (zoom_radio_action);
1897 for (node = group; node != NULL; node = g_slist_next (node)) {
1898 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1899 if (node->next != NULL) {
1900 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1903 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1911 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1913 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1914 ModestWindowPrivate *parent_priv;
1915 ModestWindowMgr *mgr;
1916 gboolean is_fullscreen;
1917 GtkAction *fs_toggle_action;
1920 mgr = modest_runtime_get_window_mgr ();
1921 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1923 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1925 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1926 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1927 if (is_fullscreen != active)
1928 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1936 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1938 ModestWindowPrivate *parent_priv;
1939 GtkAction *fs_toggle_action;
1942 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1944 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1945 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1946 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1950 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1953 ModestMsgEditWindowPrivate *priv = NULL;
1954 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1956 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1957 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1959 gtk_widget_show (priv->cc_caption);
1961 gtk_widget_hide (priv->cc_caption);
1962 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1966 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1969 ModestMsgEditWindowPrivate *priv = NULL;
1970 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1972 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1973 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1975 gtk_widget_show (priv->bcc_caption);
1977 gtk_widget_hide (priv->bcc_caption);
1978 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
1982 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1983 ModestRecptEditor *editor)
1985 ModestMsgEditWindowPrivate *priv;
1987 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1988 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1989 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1991 if (editor == NULL) {
1992 GtkWidget *view_focus;
1993 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1995 /* This code should be kept in sync with ModestRecptEditor. The
1996 textview inside the recpt editor is the one that really gets the
1997 focus. As it's inside a scrolled window, and this one inside the
1998 hbox recpt editor inherits from, we'll need to go up in the
1999 hierarchy to know if the text view is part of the recpt editor
2000 or if it's a different text entry */
2002 if (gtk_widget_get_parent (view_focus)) {
2003 GtkWidget *first_parent;
2005 first_parent = gtk_widget_get_parent (view_focus);
2006 if (gtk_widget_get_parent (first_parent) &&
2007 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2008 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2013 editor = MODEST_RECPT_EDITOR (priv->to_field);
2017 modest_address_book_select_addresses (editor);
2022 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2024 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2026 modest_msg_edit_window_open_addressbook (window, NULL);
2030 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2031 gboolean show_toolbar)
2033 ModestWindowPrivate *parent_priv;
2035 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2036 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2038 /* FIXME: we can not just use the code of
2039 modest_msg_edit_window_setup_toolbar because it has a
2040 mixture of both initialization and creation code. */
2043 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2045 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2049 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2050 TnyHeaderFlags priority_flags)
2052 ModestMsgEditWindowPrivate *priv;
2053 ModestWindowPrivate *parent_priv;
2055 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2057 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2058 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2059 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2061 if (priv->priority_flags != priority_flags) {
2062 GtkAction *priority_action = NULL;
2064 priv->priority_flags = priority_flags;
2066 switch (priority_flags) {
2067 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2068 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2069 gtk_widget_show (priv->priority_icon);
2070 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2071 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2073 case TNY_HEADER_FLAG_LOW_PRIORITY:
2074 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2075 gtk_widget_show (priv->priority_icon);
2076 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2077 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2080 gtk_widget_hide (priv->priority_icon);
2081 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2082 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2085 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2086 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2091 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2094 ModestMsgEditWindowPrivate *priv;
2095 gint current_format;
2097 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2099 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2101 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2102 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2104 if (current_format != file_format) {
2105 switch (file_format) {
2106 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2107 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2109 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2113 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2114 response = gtk_dialog_run (GTK_DIALOG (dialog));
2115 gtk_widget_destroy (dialog);
2116 if (response == GTK_RESPONSE_OK)
2117 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2121 update_dimmed (window);
2126 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2129 ModestMsgEditWindowPrivate *priv;
2130 WPTextBufferFormat oldfmt, fmt;
2131 gint old_position = 0;
2135 GdkColor *color = NULL;
2136 gboolean bold, bold_set, italic, italic_set;
2137 gboolean underline, underline_set;
2138 gboolean strikethrough, strikethrough_set;
2139 gboolean position_set;
2140 gboolean font_size_set, font_set, color_set;
2143 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2144 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2146 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2148 /* First we get the currently selected font information */
2149 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2150 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2152 switch (oldfmt.text_position) {
2153 case TEXT_POSITION_NORMAL:
2156 case TEXT_POSITION_SUPERSCRIPT:
2164 g_object_set (G_OBJECT (dialog),
2165 "bold", oldfmt.bold != FALSE,
2166 "bold-set", !oldfmt.cs.bold,
2167 "underline", oldfmt.underline != FALSE,
2168 "underline-set", !oldfmt.cs.underline,
2169 "italic", oldfmt.italic != FALSE,
2170 "italic-set", !oldfmt.cs.italic,
2171 "strikethrough", oldfmt.strikethrough != FALSE,
2172 "strikethrough-set", !oldfmt.cs.strikethrough,
2173 "color", &oldfmt.color,
2174 "color-set", !oldfmt.cs.color,
2175 "size", wp_font_size[oldfmt.font_size],
2176 "size-set", !oldfmt.cs.font_size,
2177 "position", old_position,
2178 "position-set", !oldfmt.cs.text_position,
2179 "family", wp_get_font_name (oldfmt.font),
2180 "family-set", !oldfmt.cs.font,
2183 gtk_widget_show_all (dialog);
2184 response = gtk_dialog_run (GTK_DIALOG (dialog));
2185 if (response == GTK_RESPONSE_OK) {
2187 g_object_get( dialog,
2189 "bold-set", &bold_set,
2190 "underline", &underline,
2191 "underline-set", &underline_set,
2193 "italic-set", &italic_set,
2194 "strikethrough", &strikethrough,
2195 "strikethrough-set", &strikethrough_set,
2197 "color-set", &color_set,
2199 "size-set", &font_size_set,
2200 "family", &font_name,
2201 "family-set", &font_set,
2202 "position", &position,
2203 "position-set", &position_set,
2208 if (response == GTK_RESPONSE_OK) {
2209 memset(&fmt, 0, sizeof(fmt));
2215 fmt.italic = italic;
2216 fmt.cs.italic = TRUE;
2218 if (underline_set) {
2219 fmt.underline = underline;
2220 fmt.cs.underline = TRUE;
2222 if (strikethrough_set) {
2223 fmt.strikethrough = strikethrough;
2224 fmt.cs.strikethrough = TRUE;
2229 ? TEXT_POSITION_NORMAL
2230 : ( ( position == 1 )
2231 ? TEXT_POSITION_SUPERSCRIPT
2232 : TEXT_POSITION_SUBSCRIPT );
2233 fmt.cs.text_position = TRUE;
2237 fmt.cs.color = TRUE;
2240 fmt.font = wp_get_font_index(font_name,
2245 if (font_size_set) {
2246 fmt.font_size = wp_get_font_size_index(
2247 font_size, DEFAULT_FONT_SIZE);
2248 fmt.cs.font_size = TRUE;
2250 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2252 gtk_widget_destroy (dialog);
2254 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2258 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2260 ModestMsgEditWindowPrivate *priv;
2262 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2263 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2265 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2267 update_dimmed (window);
2272 update_dimmed (ModestMsgEditWindow *window)
2274 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2275 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2279 gboolean editor_focused;
2281 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2282 editor_focused = gtk_widget_is_focus (priv->msg_body);
2284 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2285 gtk_action_set_sensitive (action, rich_text && editor_focused);
2286 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2287 gtk_action_set_sensitive (action, rich_text && editor_focused);
2288 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2289 gtk_action_set_sensitive (action, rich_text && editor_focused);
2290 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2291 gtk_action_set_sensitive (action, rich_text && editor_focused);
2292 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2293 gtk_action_set_sensitive (action, rich_text && editor_focused);
2294 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2295 gtk_action_set_sensitive (action, rich_text && editor_focused);
2296 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2297 gtk_action_set_sensitive (action, rich_text && editor_focused);
2298 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2299 gtk_action_set_sensitive (action, rich_text && editor_focused);
2300 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2301 gtk_action_set_sensitive (action, rich_text && editor_focused);
2302 widget = priv->font_color_button;
2303 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2304 widget = priv->font_size_toolitem;
2305 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2306 widget = priv->font_face_toolitem;
2307 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2311 setup_insensitive_handlers (ModestMsgEditWindow *window)
2313 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2314 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2317 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2318 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2319 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2320 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2322 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2323 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2324 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2325 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2326 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2327 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2328 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2329 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2330 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2331 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2332 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2333 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2334 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2335 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2336 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2337 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2338 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2339 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2340 widget = priv->font_color_button;
2341 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2342 widget = priv->font_size_toolitem;
2343 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2344 widget = priv->font_face_toolitem;
2345 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2347 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2348 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (remove_attachment_insensitive_press), window);
2349 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2350 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (zoom_insensitive_press), window);
2354 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2356 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2359 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2360 gtk_action_set_sensitive (action, can_undo);
2364 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2367 GtkTextIter match_start, match_end;
2369 if (image_id == NULL)
2372 gtk_text_buffer_get_start_iter (buffer, &iter);
2374 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2375 GSList *tags = gtk_text_iter_get_tags (&match_start);
2377 for (node = tags; node != NULL; node = g_slist_next (node)) {
2378 GtkTextTag *tag = (GtkTextTag *) node->data;
2379 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2380 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2381 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2383 offset = gtk_text_iter_get_offset (&match_start);
2384 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2385 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2389 gtk_text_iter_forward_char (&iter);
2394 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2396 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2397 GtkTextIter real_start, real_end;
2398 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2400 if (gtk_text_iter_compare (start, end) > 0) {
2404 real_start = *start;
2408 GSList *tags = gtk_text_iter_get_tags (&real_start);
2410 for (node = tags; node != NULL; node = g_slist_next (node)) {
2411 GtkTextTag *tag = (GtkTextTag *) node->data;
2412 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2413 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2415 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2417 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2420 } while (gtk_text_iter_forward_char (&real_start)&&
2421 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2425 msg_body_focus (GtkWidget *focus,
2426 GdkEventFocus *event,
2430 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2435 recpt_field_changed (GtkTextBuffer *buffer,
2436 ModestMsgEditWindow *editor)
2438 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2439 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2440 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2441 gboolean dim = FALSE;
2444 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2445 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2446 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2448 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2449 gtk_text_buffer_get_char_count (cc_buffer) +
2450 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2452 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2453 gtk_action_set_sensitive (action, !dim);
2454 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2455 gtk_action_set_sensitive (action, !dim);
2459 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2461 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2465 zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2467 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2471 remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2473 ModestWindowPrivate *parent_priv;
2474 ModestMsgEditWindowPrivate *priv;
2475 GList *selected_attachments = NULL;
2476 gint n_att_selected = 0;
2478 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2479 parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2481 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2482 n_att_selected = g_list_length (selected_attachments);
2483 g_list_free (selected_attachments);
2485 if (n_att_selected > 1)
2486 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
2487 else if (n_att_selected == 0)
2488 hildon_banner_show_information (NULL, NULL, _("TODO: select one attachment"));
2493 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2495 gboolean rich_text, editor_focused;
2497 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2498 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2499 editor_focused = gtk_widget_is_focus (priv->msg_body);
2502 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2503 else if (!editor_focused)
2504 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2508 reset_modified (ModestMsgEditWindow *editor)
2510 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2511 GtkTextBuffer *buffer;
2513 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2514 gtk_text_buffer_set_modified (buffer, FALSE);
2515 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2516 gtk_text_buffer_set_modified (buffer, FALSE);
2517 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2518 gtk_text_buffer_set_modified (buffer, FALSE);
2519 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2523 modest_msg_edit_window_is_modified (ModestMsgEditWindow *editor)
2525 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2526 GtkTextBuffer *buffer;
2528 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2529 if (gtk_text_buffer_get_modified (buffer))
2531 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2532 if (gtk_text_buffer_get_modified (buffer))
2534 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2535 if (gtk_text_buffer_get_modified (buffer))
2537 if (gtk_text_buffer_get_modified (priv->text_buffer))
2544 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2546 ModestMsgEditWindowPrivate *priv = NULL;
2548 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2549 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2551 /* check if there's no recipient added */
2552 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2553 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2554 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2555 /* no recipient contents, then select contacts */
2556 modest_msg_edit_window_open_addressbook (window, NULL);
2560 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2562 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2564 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2567 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2574 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2575 ModestMsgEditWindow *window)
2577 modest_msg_edit_window_attach_file (window);
2581 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2583 ModestMsgEditWindow *window)
2585 ModestWindowPrivate *parent_priv;
2586 ModestMsgEditWindowPrivate *priv;
2590 GList *selected_attachments = NULL;
2591 gint n_att_selected = 0;
2593 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2594 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2595 selection = gtk_clipboard_wait_for_text (clipboard);
2596 focused = gtk_window_get_focus (GTK_WINDOW (window));
2598 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2599 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2600 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2601 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2603 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2604 n_att_selected = g_list_length (selected_attachments);
2605 g_list_free (selected_attachments);
2607 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2608 gtk_action_set_sensitive (action, n_att_selected == 1);
2611 update_paste_dimming (window);
2615 update_window_title (ModestMsgEditWindow *window)
2617 ModestMsgEditWindowPrivate *priv = NULL;
2618 const gchar *subject;
2620 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2621 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2622 if (subject == NULL || subject[0] == '\0')
2623 subject = _("mail_va_new_email");
2625 gtk_window_set_title (GTK_WINDOW (window), subject);
2630 subject_field_changed (GtkEditable *editable,
2631 ModestMsgEditWindow *window)
2633 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2634 update_window_title (window);
2635 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2639 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2642 ModestMsgEditWindowPrivate *priv = NULL;
2644 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2645 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2647 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2649 gtk_widget_show_all (priv->find_toolbar);
2650 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2652 gtk_widget_hide_all (priv->find_toolbar);
2653 gtk_widget_grab_focus (priv->msg_body);
2659 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2660 ModestMsgEditWindow *window)
2662 gchar *current_search = NULL;
2663 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2665 GtkTextIter selection_start, selection_end;
2666 GtkTextIter match_start, match_end;
2668 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2669 if ((current_search == NULL) && (strcmp (current_search, "") == 0)) {
2670 g_free (current_search);
2674 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2675 result = gtk_text_iter_forward_search (&selection_end, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, NULL);
2677 GtkTextIter buffer_start;
2678 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2679 result = gtk_text_iter_forward_search (&buffer_start, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, &selection_start);
2682 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2683 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2685 /* TODO: warning about non succesful search */
2687 g_free (current_search);
2691 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2692 ModestMsgEditWindow *window)
2694 GtkToggleAction *toggle;
2695 ModestWindowPrivate *parent_priv;
2696 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2698 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2699 gtk_toggle_action_set_active (toggle, FALSE);
2704 update_paste_dimming (ModestMsgEditWindow *window)
2706 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2707 GtkAction *action = NULL;
2708 GtkClipboard *clipboard = NULL;
2710 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2712 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2713 gtk_action_set_sensitive (action, gtk_clipboard_wait_is_text_available (clipboard));
2718 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2720 ModestMsgEditWindow *window)
2722 update_paste_dimming (window);
2726 update_select_all_dimming (ModestMsgEditWindow *window)
2729 gboolean dimmed = FALSE;
2731 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2733 focused = gtk_window_get_focus (GTK_WINDOW (window));
2734 if (GTK_IS_ENTRY (focused)) {
2735 const gchar *current_text;
2736 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2737 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2738 } else if (GTK_IS_TEXT_VIEW (focused)) {
2739 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2740 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2741 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2744 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2745 gtk_action_set_sensitive (action, !dimmed);
2749 update_zoom_dimming (ModestMsgEditWindow *window)
2752 gboolean dimmed = FALSE;
2754 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2756 focused = gtk_window_get_focus (GTK_WINDOW (window));
2757 dimmed = ! WP_IS_TEXT_VIEW (focused);
2758 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2759 gtk_action_set_sensitive (action, !dimmed);
2763 edit_menu_activated (GtkAction *action,
2766 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2768 update_select_all_dimming (window);
2771 view_menu_activated (GtkAction *action,
2774 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2776 update_zoom_dimming (window);