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 #include "widgets/modest-msg-edit-window-ui.h"
67 #include <libgnomevfs/gnome-vfs-mime.h>
68 #include "modest-maemo-utils.h"
71 #define DEFAULT_FONT_SIZE 3
72 #define DEFAULT_FONT 2
73 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
74 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
75 #define DEFAULT_MAIN_VBOX_SPACING 6
76 #define SUBJECT_MAX_LENGTH 1000
77 #define IMAGE_MAX_WIDTH 640
79 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
80 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
81 static void modest_msg_edit_window_finalize (GObject *obj);
83 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
84 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
85 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
86 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
87 static void remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
88 static void zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
89 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
90 static void reset_modified (ModestMsgEditWindow *editor);
91 static gboolean is_modified (ModestMsgEditWindow *editor);
93 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
94 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
95 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
96 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
97 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
98 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
100 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
102 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
104 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
105 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
106 GdkEventWindowState *event,
108 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
109 ModestRecptEditor *editor);
110 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
111 ModestMsgEditWindow *window);
113 /* ModestWindow methods implementation */
114 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
115 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
116 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
117 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
118 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
119 gboolean show_toolbar);
120 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
122 ModestMsgEditWindow *window);
123 static void modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
125 ModestMsgEditWindow *window);
126 static void update_window_title (ModestMsgEditWindow *window);
127 static void update_dimmed (ModestMsgEditWindow *window);
128 static void update_paste_dimming (ModestMsgEditWindow *window);
129 static void update_select_all_dimming (ModestMsgEditWindow *window);
130 static void update_zoom_dimming (ModestMsgEditWindow *window);
133 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
134 ModestMsgEditWindow *window);
135 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
136 ModestMsgEditWindow *window);
137 static void edit_menu_activated (GtkAction *action,
139 static void view_menu_activated (GtkAction *action,
142 /* list my signals */
149 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
150 struct _ModestMsgEditWindowPrivate {
152 GtkWidget *header_box;
154 ModestPairList *from_field_protos;
155 GtkWidget *from_field;
159 GtkWidget *bcc_field;
160 GtkWidget *subject_field;
161 GtkWidget *attachments_view;
162 GtkWidget *priority_icon;
163 GtkWidget *add_attachment_button;
165 GtkWidget *cc_caption;
166 GtkWidget *bcc_caption;
167 GtkWidget *attachments_caption;
169 GtkTextBuffer *text_buffer;
171 GtkWidget *font_size_toolitem;
172 GtkWidget *font_face_toolitem;
173 GtkWidget *font_color_button;
174 GSList *font_items_group;
175 GtkWidget *font_tool_button_label;
176 GSList *size_items_group;
177 GtkWidget *size_tool_button_label;
179 GtkWidget *find_toolbar;
182 GtkWidget *scroll_area;
187 TnyHeaderFlags priority_flags;
191 gulong clipboard_change_handler_id;
192 gulong system_clipboard_change_handler_id;
197 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
198 MODEST_TYPE_MSG_EDIT_WINDOW, \
199 ModestMsgEditWindowPrivate))
201 static GtkWindowClass *parent_class = NULL;
203 /* uncomment the following if you have defined any signals */
204 /* static guint signals[LAST_SIGNAL] = {0}; */
207 modest_msg_edit_window_get_type (void)
209 static GType my_type = 0;
211 static const GTypeInfo my_info = {
212 sizeof(ModestMsgEditWindowClass),
213 NULL, /* base init */
214 NULL, /* base finalize */
215 (GClassInitFunc) modest_msg_edit_window_class_init,
216 NULL, /* class finalize */
217 NULL, /* class data */
218 sizeof(ModestMsgEditWindow),
220 (GInstanceInitFunc) modest_msg_edit_window_init,
223 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
224 "ModestMsgEditWindow",
227 wp_text_buffer_library_init ();
233 save_state (ModestWindow *self)
235 modest_widget_memory_save (modest_runtime_get_conf(),
236 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
241 restore_settings (ModestMsgEditWindow *self)
243 modest_widget_memory_restore (modest_runtime_get_conf(),
244 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
249 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
251 GObjectClass *gobject_class;
252 ModestWindowClass *modest_window_class;
253 gobject_class = (GObjectClass*) klass;
254 modest_window_class = (ModestWindowClass*) klass;
256 parent_class = g_type_class_peek_parent (klass);
257 gobject_class->finalize = modest_msg_edit_window_finalize;
259 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
260 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
261 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
262 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
263 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
265 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
267 modest_window_class->save_state_func = save_state;
271 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
273 ModestMsgEditWindowPrivate *priv;
274 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
276 priv->msg_body = NULL;
277 priv->from_field = NULL;
278 priv->to_field = NULL;
279 priv->cc_field = NULL;
280 priv->bcc_field = NULL;
281 priv->subject_field = NULL;
282 priv->attachments = NULL;
284 priv->zoom_level = 1.0;
286 priv->cc_caption = NULL;
287 priv->bcc_caption = NULL;
289 priv->priority_flags = 0;
291 priv->find_toolbar = NULL;
293 priv->draft_msg = NULL;
294 priv->clipboard_change_handler_id = 0;
295 priv->system_clipboard_change_handler_id = 0;
299 /* FIXME: this is a dup from the one in gtk/ */
302 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
304 static ModestPairList*
305 get_transports (void)
307 GSList *transports = NULL;
309 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
310 GSList *accounts = modest_account_mgr_account_names (account_mgr,
311 TRUE /* only enabled accounts. */);
313 GSList *cursor = accounts;
315 gchar *account_name = cursor->data;
316 gchar *from_string = NULL;
318 from_string = modest_account_mgr_get_from_string (account_mgr,
322 if (from_string && account_name) {
323 gchar *name = account_name;
324 ModestPair *pair = modest_pair_new ((gpointer) name,
325 (gpointer) from_string , TRUE);
326 transports = g_slist_prepend (transports, pair);
329 cursor = cursor->next;
331 g_slist_free (accounts); /* only free the accounts, not the elements,
332 * because they are used in the pairlist */
338 init_window (ModestMsgEditWindow *obj)
340 GtkWidget *from_caption, *to_caption, *subject_caption;
341 GtkWidget *main_vbox;
342 ModestMsgEditWindowPrivate *priv;
344 GtkSizeGroup *size_group;
346 GtkWidget *subject_box;
347 GtkWidget *attachment_icon;
348 GtkWidget *window_box;
350 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
352 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
354 /* Note: This ModestPairList* must exist for as long as the combo
355 * that uses it, because the ModestComboBox uses the ID opaquely,
356 * so it can't know how to manage its memory. */
357 priv->from_field_protos = get_transports ();
359 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
361 priv->to_field = modest_recpt_editor_new ();
362 priv->cc_field = modest_recpt_editor_new ();
363 priv->bcc_field = modest_recpt_editor_new ();
364 subject_box = gtk_hbox_new (FALSE, 0);
365 priv->priority_icon = gtk_image_new ();
366 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
367 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
368 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
369 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
370 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
371 priv->add_attachment_button = gtk_button_new ();
372 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
373 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
374 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
375 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
376 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
377 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
378 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
379 priv->attachments_view = modest_attachments_view_new (NULL);
381 priv->header_box = gtk_vbox_new (FALSE, 0);
383 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
384 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
385 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
386 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
387 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
388 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
389 g_object_unref (size_group);
391 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
392 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
393 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
394 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
395 gtk_size_group_add_widget (size_group, priv->subject_field);
396 gtk_size_group_add_widget (size_group, priv->attachments_view);
397 g_object_unref (size_group);
399 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
400 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
401 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
402 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
403 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
404 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
405 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
408 priv->msg_body = wp_text_view_new ();
409 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
410 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
411 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
412 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
413 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
414 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
416 priv->find_toolbar = hildon_find_toolbar_new (NULL);
417 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
419 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
420 G_CALLBACK (text_buffer_refresh_attributes), obj);
421 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
422 G_CALLBACK (text_buffer_delete_range), obj);
423 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
424 G_CALLBACK (text_buffer_can_undo), obj);
425 g_signal_connect (G_OBJECT (obj), "window-state-event",
426 G_CALLBACK (modest_msg_edit_window_window_state_event),
428 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
429 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
430 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
431 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
432 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
433 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
435 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
436 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
438 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
439 G_CALLBACK (msg_body_focus), obj);
440 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
441 G_CALLBACK (msg_body_focus), obj);
442 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
443 "changed", G_CALLBACK (recpt_field_changed), obj);
444 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
445 "changed", G_CALLBACK (recpt_field_changed), obj);
446 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
447 "changed", G_CALLBACK (recpt_field_changed), obj);
448 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
449 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
451 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
452 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
454 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
455 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
456 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
458 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
460 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
461 frame = gtk_frame_new (NULL);
462 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
464 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
465 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
466 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
468 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
469 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
470 gtk_widget_hide (priv->cc_caption);
472 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
473 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
474 gtk_widget_hide (priv->bcc_caption);
477 window_box = gtk_vbox_new (FALSE, 0);
478 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
479 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
480 gtk_container_add (GTK_CONTAINER(obj), window_box);
481 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
482 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
485 TODO: scroll_area was never instantiated.
486 Stop building without warnings-as-errors. murrayc.
487 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
488 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
491 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
492 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
493 priv->system_clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
494 G_CALLBACK (modest_msg_edit_window_system_clipboard_owner_change), obj);
500 modest_msg_edit_window_finalize (GObject *obj)
502 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
504 if (priv->clipboard_change_handler_id > 0) {
505 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
506 priv->clipboard_change_handler_id = 0;
509 if (priv->system_clipboard_change_handler_id > 0) {
510 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
511 priv->system_clipboard_change_handler_id);
512 priv->system_clipboard_change_handler_id = 0;
515 /* This had to stay alive for as long as the combobox that used it: */
516 modest_pair_list_free (priv->from_field_protos);
518 G_OBJECT_CLASS(parent_class)->finalize (obj);
522 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
524 GtkWidget *close_dialog;
525 ModestMsgEditWindowPrivate *priv;
528 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
529 modest_window_save_state (MODEST_WINDOW (self));
530 if (is_modified (self)) {
531 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
532 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
533 gtk_widget_destroy (close_dialog);
535 if (response != GTK_RESPONSE_CANCEL) {
536 modest_ui_actions_on_save_to_drafts (NULL, self);
539 /* /\* remove old message from drafts *\/ */
540 /* if (priv->draft_msg) { */
541 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
542 /* TnyAccount *account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(), */
544 /* TNY_ACCOUNT_TYPE_STORE); */
545 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
546 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
547 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
548 /* tny_folder_remove_msg (folder, header, NULL); */
549 /* g_object_unref (folder); */
550 /* g_object_unref (header); */
551 /* g_object_unref (priv->draft_msg); */
552 /* priv->draft_msg = NULL; */
554 gtk_widget_destroy (GTK_WIDGET (self));
560 menubar_to_menu (GtkUIManager *ui_manager)
562 GtkWidget *main_menu;
566 /* Create new main menu */
567 main_menu = gtk_menu_new();
569 /* Get the menubar from the UI manager */
570 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
572 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
576 menu = GTK_WIDGET (iter->data);
577 gtk_widget_reparent(menu, main_menu);
579 iter = g_list_next (iter);
586 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
589 const gchar *to, *cc, *bcc, *subject;
591 ModestMsgEditWindowPrivate *priv;
593 TnyHeaderFlags priority_flags;
595 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
596 g_return_if_fail (TNY_IS_MSG (msg));
598 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
600 header = tny_msg_get_header (msg);
601 to = tny_header_get_to (header);
602 cc = tny_header_get_cc (header);
603 bcc = tny_header_get_bcc (header);
604 subject = tny_header_get_subject (header);
605 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
608 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
610 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
612 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
614 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
615 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
618 update_window_title (self);
620 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
621 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
622 body = modest_tny_msg_get_body (msg, TRUE);
624 if ((body == NULL)||(body[0] == '\0')) {
626 body = modest_text_utils_convert_to_html ("");
628 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
629 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
632 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
635 /* Get the default format required from configuration */
636 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
637 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
640 /* Set the default focus depending on having already a To: field or not */
641 if ((!to)||(*to == '\0')) {
642 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
644 gtk_widget_grab_focus (priv->msg_body);
647 /* TODO: lower priority, select in the From: combo to the
648 value that comes from msg <- not sure, should it be
651 /* Add attachments to the view */
652 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
653 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
654 if (priv->attachments == NULL) {
655 gtk_widget_hide (priv->attachments_caption);
657 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
658 gtk_widget_show_all (priv->attachments_caption);
661 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
662 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
664 reset_modified (self);
666 update_dimmed (self);
667 text_buffer_can_undo (priv->text_buffer, FALSE, self);
669 priv->draft_msg = msg;
673 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
676 GList *item_children, *node;
677 GtkWidget *bin_child;
679 bin_child = gtk_bin_get_child (GTK_BIN(item));
681 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
683 for (node = item_children; node != NULL; node = g_list_next (node)) {
684 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
685 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
688 g_list_free (item_children);
692 menu_tool_button_dont_expand (GtkMenuToolButton *item)
695 GList *item_children, *node;
697 box = gtk_bin_get_child (GTK_BIN (item));
698 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
699 item_children = gtk_container_get_children (GTK_CONTAINER (box));
701 for (node = item_children; node != NULL; node = g_list_next (node)) {
702 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
703 if (GTK_IS_TOGGLE_BUTTON (node->data))
704 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
705 else if (GTK_IS_BUTTON (node->data))
706 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
708 g_list_free (item_children);
713 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
715 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
716 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
717 GtkWidget *placeholder;
718 GtkWidget *tool_item;
723 GtkWidget *sizes_menu;
724 GtkWidget *fonts_menu;
725 GSList *radio_group = NULL;
730 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
731 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
733 /* should we hide the toolbar? */
734 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
735 gtk_widget_hide (parent_priv->toolbar);
737 /* Font color placeholder */
738 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
739 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
742 tool_item = GTK_WIDGET (gtk_tool_item_new ());
743 priv->font_color_button = hildon_color_button_new ();
744 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
745 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
746 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
747 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
748 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
749 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
750 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
752 /* Font size and face placeholder */
753 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
754 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
756 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
757 priv->size_tool_button_label = gtk_label_new (NULL);
758 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
759 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
760 size_text,"</span>", NULL);
761 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
763 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
764 sizes_menu = gtk_menu_new ();
765 priv->size_items_group = NULL;
767 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
768 GtkWidget *size_menu_item;
770 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
771 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
772 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
773 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
774 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
775 gtk_widget_show (size_menu_item);
777 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
781 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
782 GtkWidget *item = (GtkWidget *) node->data;
783 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
787 priv->size_items_group = g_slist_reverse (priv->size_items_group);
788 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
789 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
790 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
791 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
792 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
793 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
794 priv->font_size_toolitem = tool_item;
797 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
798 priv->font_tool_button_label = gtk_label_new (NULL);
799 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
800 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
802 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
803 fonts_menu = gtk_menu_new ();
804 priv->font_items_group = NULL;
806 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
807 GtkWidget *font_menu_item;
808 GtkWidget *child_label;
810 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
811 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
812 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
813 wp_get_font_name (font_index), "</span>", NULL);
814 gtk_label_set_markup (GTK_LABEL (child_label), markup);
817 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
818 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
819 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
820 gtk_widget_show (font_menu_item);
822 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
825 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
826 GtkWidget *item = (GtkWidget *) node->data;
827 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
830 priv->font_items_group = g_slist_reverse (priv->font_items_group);
831 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
832 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
833 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
834 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
835 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
836 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
837 priv->font_face_toolitem = tool_item;
839 /* Set expand and homogeneous for remaining items */
840 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
841 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
842 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
843 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
844 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
845 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
846 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
847 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
848 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
856 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
859 ModestWindowPrivate *parent_priv;
860 ModestMsgEditWindowPrivate *priv;
861 GtkActionGroup *action_group;
862 GError *error = NULL;
863 GdkPixbuf *window_icon = NULL;
866 gboolean prefer_formatted;
868 ModestPair *account_pair = NULL;
870 g_return_val_if_fail (msg, NULL);
871 g_return_val_if_fail (account_name, NULL);
873 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
875 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
876 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
878 parent_priv->ui_manager = gtk_ui_manager_new();
879 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
880 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
882 /* Add common actions */
883 gtk_action_group_add_actions (action_group,
884 modest_msg_edit_action_entries,
885 G_N_ELEMENTS (modest_msg_edit_action_entries),
887 gtk_action_group_add_toggle_actions (action_group,
888 modest_msg_edit_toggle_action_entries,
889 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
891 gtk_action_group_add_radio_actions (action_group,
892 modest_msg_edit_alignment_radio_action_entries,
893 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
895 G_CALLBACK (modest_ui_actions_on_change_justify),
897 gtk_action_group_add_radio_actions (action_group,
898 modest_msg_edit_zoom_action_entries,
899 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
901 G_CALLBACK (modest_ui_actions_on_change_zoom),
903 gtk_action_group_add_radio_actions (action_group,
904 modest_msg_edit_priority_action_entries,
905 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
907 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
909 gtk_action_group_add_radio_actions (action_group,
910 modest_msg_edit_file_format_action_entries,
911 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
912 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
913 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
915 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
916 g_object_unref (action_group);
918 /* Load the UI definition */
919 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
922 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
923 g_clear_error (&error);
926 /* Add accelerators */
927 gtk_window_add_accel_group (GTK_WINDOW (obj),
928 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
931 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
932 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
935 init_window (MODEST_MSG_EDIT_WINDOW(obj));
937 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
939 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
941 g_signal_connect (G_OBJECT(obj), "delete-event",
942 G_CALLBACK(on_delete_event), obj);
944 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
946 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
948 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
950 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
951 if (account_pair != NULL)
952 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
954 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
956 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
958 /* Set window icon */
959 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
960 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
962 /* Dim at start clipboard actions */
963 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
964 gtk_action_set_sensitive (action, FALSE);
965 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
966 gtk_action_set_sensitive (action, FALSE);
967 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
968 gtk_action_set_sensitive (action, FALSE);
970 /* Update select all */
971 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
972 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
973 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
974 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
975 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
977 /* set initial state of cc and bcc */
978 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
979 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
980 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
981 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
982 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
983 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
985 /* Setup the file format */
986 conf = modest_runtime_get_conf ();
987 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
989 g_clear_error (&error);
990 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
992 file_format = (prefer_formatted) ?
993 MODEST_FILE_FORMAT_FORMATTED_TEXT :
994 MODEST_FILE_FORMAT_PLAIN_TEXT;
995 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
997 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
999 return (ModestWindow*) obj;
1003 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1005 GString **string_buffer = (GString **) user_data;
1007 *string_buffer = g_string_append (*string_buffer, buffer);
1013 * @result: A new string which should be freed with g_free().
1016 get_formatted_data (ModestMsgEditWindow *edit_window)
1018 ModestMsgEditWindowPrivate *priv;
1019 GString *string_buffer = g_string_new ("");
1021 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1023 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1025 return g_string_free (string_buffer, FALSE);
1030 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1033 const gchar *account_name;
1034 ModestMsgEditWindowPrivate *priv;
1036 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1038 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1040 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1041 g_return_val_if_fail (account_name, NULL);
1044 /* don't free these (except from) */
1045 data = g_slice_new0 (MsgData);
1046 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1048 data->account_name = g_strdup (account_name);
1049 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1050 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1051 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1052 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1053 if (priv->draft_msg) {
1054 data->draft_msg = g_object_ref (priv->draft_msg);
1056 data->draft_msg = NULL;
1059 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1061 gtk_text_buffer_get_bounds (buf, &b, &e);
1062 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1064 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1065 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1067 data->html_body = NULL;
1069 data->attachments = priv->attachments; /* TODO: copy and free ? */
1070 data->priority_flags = priv->priority_flags;
1075 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1077 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1080 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1088 g_free (data->subject);
1089 g_free (data->plain_body);
1090 g_free (data->html_body);
1091 if (data->draft_msg != NULL) {
1092 g_object_unref (data->draft_msg);
1093 data->draft_msg = NULL;
1095 g_free (data->account_name);
1097 /* TODO: Free data->attachments? */
1099 g_slice_free (MsgData, data);
1103 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1106 ModestMsgEditWindowPrivate *priv = NULL;
1107 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1109 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1111 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1113 return MODEST_MSG_EDIT_FORMAT_HTML;
1115 return MODEST_MSG_EDIT_FORMAT_TEXT;
1119 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1120 ModestMsgEditFormat format)
1122 ModestMsgEditWindowPrivate *priv;
1124 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1125 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1128 case MODEST_MSG_EDIT_FORMAT_HTML:
1129 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1131 case MODEST_MSG_EDIT_FORMAT_TEXT:
1132 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1135 g_return_if_reached ();
1139 ModestMsgEditFormatState *
1140 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1142 ModestMsgEditFormatState *format_state = NULL;
1143 ModestMsgEditWindowPrivate *priv;
1144 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1146 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1147 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1149 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1151 format_state = g_new0 (ModestMsgEditFormatState, 1);
1152 format_state->bold = buffer_format->bold&0x1;
1153 format_state->italics = buffer_format->italic&0x1;
1154 format_state->bullet = buffer_format->bullet&0x1;
1155 format_state->color = buffer_format->color;
1156 format_state->font_size = buffer_format->font_size;
1157 format_state->font_family = wp_get_font_name (buffer_format->font);
1158 format_state->justification = buffer_format->justification;
1159 g_free (buffer_format);
1161 return format_state;
1166 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1167 const ModestMsgEditFormatState *format_state)
1169 ModestMsgEditWindowPrivate *priv;
1170 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1171 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1172 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1173 g_return_if_fail (format_state != NULL);
1175 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1176 gtk_widget_grab_focus (priv->msg_body);
1177 buffer_format->bold = (format_state->bold != FALSE);
1178 buffer_format->italic = (format_state->italics != FALSE);
1179 buffer_format->color = format_state->color;
1180 buffer_format->font_size = format_state->font_size;
1181 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1182 buffer_format->justification = format_state->justification;
1183 buffer_format->bullet = format_state->bullet;
1185 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1187 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1188 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1189 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1190 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1191 buffer_format->cs.font = (buffer_format->font != current_format->font);
1192 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1193 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1195 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1196 if (buffer_format->cs.bold) {
1197 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1199 if (buffer_format->cs.italic) {
1200 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1202 if (buffer_format->cs.color) {
1203 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1205 if (buffer_format->cs.font_size) {
1206 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1208 if (buffer_format->cs.justification) {
1209 switch (buffer_format->justification) {
1210 case GTK_JUSTIFY_LEFT:
1211 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1213 case GTK_JUSTIFY_CENTER:
1214 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1216 case GTK_JUSTIFY_RIGHT:
1217 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1224 if (buffer_format->cs.font) {
1225 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1227 if (buffer_format->cs.bullet) {
1228 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1230 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1231 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1233 g_free (current_format);
1238 toggle_action_set_active_block_notify (GtkToggleAction *action,
1241 GSList *proxies = NULL;
1243 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1244 proxies != NULL; proxies = g_slist_next (proxies)) {
1245 GtkWidget *widget = (GtkWidget *) proxies->data;
1246 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1249 gtk_toggle_action_set_active (action, value);
1251 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1252 proxies != NULL; proxies = g_slist_next (proxies)) {
1253 GtkWidget *widget = (GtkWidget *) proxies->data;
1254 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1259 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1261 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1263 ModestWindowPrivate *parent_priv;
1264 ModestMsgEditWindowPrivate *priv;
1265 GtkWidget *new_size_menuitem;
1266 GtkWidget *new_font_menuitem;
1268 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1269 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1271 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1272 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1273 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1274 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1276 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1277 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1278 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1281 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1283 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1284 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1286 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1287 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1289 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1290 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1292 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1293 G_CALLBACK (modest_msg_edit_window_color_button_change),
1295 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1296 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1297 G_CALLBACK (modest_msg_edit_window_color_button_change),
1300 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1301 buffer_format->font_size))->data);
1302 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1306 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1307 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1308 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1310 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1311 G_CALLBACK (modest_msg_edit_window_size_change),
1313 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1314 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1315 G_CALLBACK (modest_msg_edit_window_size_change),
1319 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1320 buffer_format->font))->data);
1321 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1325 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1326 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1327 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1329 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1330 G_CALLBACK (modest_msg_edit_window_font_change),
1332 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1333 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1334 G_CALLBACK (modest_msg_edit_window_font_change),
1338 g_free (buffer_format);
1344 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1347 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1348 ModestMsgEditWindowPrivate *priv;
1349 GtkWidget *dialog = NULL;
1351 const GdkColor *new_color = NULL;
1353 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1354 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1356 #ifdef MODEST_HILDON_VERSION_0
1357 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1358 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1360 dialog = hildon_color_chooser_new ();
1361 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1362 #endif /*MODEST_HILDON_VERSION_0*/
1363 g_free (buffer_format);
1365 response = gtk_dialog_run (GTK_DIALOG (dialog));
1367 case GTK_RESPONSE_OK: {
1368 #ifdef MODEST_HILDON_VERSION_0
1369 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1372 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1374 #endif /*MODEST_HILDON_VERSION_0*/
1381 gtk_widget_destroy (dialog);
1383 if (new_color != NULL)
1384 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1389 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1392 ModestMsgEditWindowPrivate *priv;
1393 GtkWidget *dialog = NULL;
1395 GdkColor *old_color = NULL;
1396 const GdkColor *new_color = NULL;
1398 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1399 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1401 #ifdef MODEST_HILDON_VERSION_0
1402 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1403 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1405 dialog = hildon_color_chooser_new ();
1406 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1407 #endif /*MODEST_HILDON_VERSION_9*/
1409 response = gtk_dialog_run (GTK_DIALOG (dialog));
1411 case GTK_RESPONSE_OK: {
1412 #ifdef MODEST_HILDON_VERSION_0
1413 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1416 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1418 #endif /*MODEST_HILDON_VERSION_0*/
1424 gtk_widget_destroy (dialog);
1426 if (new_color != NULL)
1427 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1433 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1436 ModestMsgEditWindowPrivate *priv;
1437 GtkWidget *dialog = NULL;
1439 GSList *uris = NULL;
1440 GSList *uri_node = NULL;
1442 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1444 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1445 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1446 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1448 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1450 response = gtk_dialog_run (GTK_DIALOG (dialog));
1452 case GTK_RESPONSE_OK:
1453 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1458 gtk_widget_destroy (dialog);
1460 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1462 GnomeVFSHandle *handle = NULL;
1463 GnomeVFSResult result;
1464 GtkTextIter position;
1465 GtkTextMark *insert_mark;
1467 uri = (const gchar *) uri_node->data;
1468 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1469 if (result == GNOME_VFS_OK) {
1470 GdkPixbufLoader *loader;
1472 GnomeVFSFileInfo info;
1473 gchar *filename, *basename;
1474 TnyMimePart *mime_part;
1477 const gchar *mime_type = NULL;
1479 filename = g_filename_from_uri (uri, NULL, NULL);
1480 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1482 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1484 mime_part = tny_platform_factory_new_mime_part
1485 (modest_runtime_get_platform_factory ());
1486 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1488 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1490 content_id = g_strdup_printf ("%d", priv->last_cid);
1491 tny_mime_part_set_content_id (mime_part, content_id);
1492 g_free (content_id);
1495 basename = g_path_get_basename (filename);
1496 tny_mime_part_set_filename (mime_part, basename);
1499 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1500 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1502 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1503 gtk_widget_show_all (priv->attachments_caption);
1504 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1507 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1508 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1509 char read_buffer[128];
1511 readed = tny_stream_read (TNY_STREAM (stream), read_buffer, 128);
1512 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1515 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1516 g_object_ref (pixbuf);
1517 gdk_pixbuf_loader_close (loader, NULL);
1518 g_object_unref (loader);
1520 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1521 GdkPixbuf *new_pixbuf;
1523 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1524 gdk_pixbuf_get_width (pixbuf);
1525 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1526 g_object_unref (pixbuf);
1527 pixbuf = new_pixbuf;
1530 if (pixbuf != NULL) {
1531 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1532 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1533 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1542 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1545 ModestMsgEditWindowPrivate *priv;
1546 GtkWidget *dialog = NULL;
1548 GSList *uris = NULL;
1551 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1553 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1554 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1556 response = gtk_dialog_run (GTK_DIALOG (dialog));
1558 case GTK_RESPONSE_OK:
1559 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1564 gtk_widget_destroy (dialog);
1566 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1568 GnomeVFSHandle *handle = NULL;
1569 GnomeVFSResult result;
1571 uri = (const gchar *) uri_node->data;
1572 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1573 if (result == GNOME_VFS_OK) {
1574 TnyMimePart *mime_part;
1576 const gchar *mime_type = NULL;
1580 GnomeVFSFileInfo info;
1582 filename = g_filename_from_uri (uri, NULL, NULL);
1584 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1585 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1586 mime_part = tny_platform_factory_new_mime_part
1587 (modest_runtime_get_platform_factory ());
1588 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1590 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1592 content_id = g_strdup_printf ("%d", priv->last_cid);
1593 tny_mime_part_set_content_id (mime_part, content_id);
1594 g_free (content_id);
1597 basename = g_path_get_basename (filename);
1598 tny_mime_part_set_filename (mime_part, basename);
1601 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1602 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1604 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1605 gtk_widget_show_all (priv->attachments_caption);
1606 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1611 g_slist_foreach (uris, (GFunc) g_free, NULL);
1612 g_slist_free (uris);
1616 modest_msg_edit_window_attach_file_noninteractive (
1617 ModestMsgEditWindow *window,
1618 const gchar *file_uri)
1621 ModestMsgEditWindowPrivate *priv;
1623 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1628 /* TODO: We should probably try to use only the URI,
1629 * instead of using a filename.
1631 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1633 g_warning("%s: g_filename_from_uri(%s) failed.\n", __FUNCTION__, file_uri);
1636 file_id = g_open (filename, O_RDONLY, 0);
1637 if (file_id != -1) {
1638 TnyMimePart *mime_part;
1640 const gchar *mime_type;
1644 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1645 mime_part = tny_platform_factory_new_mime_part
1646 (modest_runtime_get_platform_factory ());
1647 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1649 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1651 content_id = g_strdup_printf ("%d", priv->last_cid);
1652 tny_mime_part_set_content_id (mime_part, content_id);
1653 g_free (content_id);
1656 basename = g_path_get_basename (filename);
1657 tny_mime_part_set_filename (mime_part, basename);
1660 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1661 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1663 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1664 gtk_widget_show_all (priv->attachments_caption);
1665 } else if (file_id == -1) {
1667 g_warning("file to be attached does not exist: %s", filename);
1675 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1678 ModestMsgEditWindowPrivate *priv;
1679 gboolean clean_list = FALSE;
1681 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1682 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1684 if (att_list == NULL) {
1685 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1689 if (att_list == NULL) {
1690 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1692 GtkWidget *confirmation_dialog = NULL;
1693 gboolean dialog_response;
1695 gchar *message = NULL;
1696 const gchar *filename = NULL;
1698 if (att_list->next == NULL) {
1699 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1703 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1704 att_list->next == NULL), filename);
1705 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1707 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1708 gtk_widget_destroy (confirmation_dialog);
1709 if (!dialog_response) {
1711 g_list_free (att_list);
1714 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1716 for (node = att_list; node != NULL; node = g_list_next (node)) {
1717 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1718 const gchar *att_id;
1719 priv->attachments = g_list_remove (priv->attachments, mime_part);
1721 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1723 if (priv->attachments == NULL)
1724 gtk_widget_hide (priv->attachments_caption);
1725 att_id = tny_mime_part_get_content_id (mime_part);
1727 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1729 g_object_unref (mime_part);
1730 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1735 g_list_free (att_list);
1739 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1742 ModestMsgEditWindowPrivate *priv;
1743 GdkColor *new_color;
1744 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1746 #ifdef MODEST_HILDON_VERSION_0
1747 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1750 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1752 #endif /*MODEST_HILDON_VERSION_0*/
1754 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1756 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1761 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1764 ModestMsgEditWindowPrivate *priv;
1765 gint new_size_index;
1766 ModestMsgEditWindow *window;
1769 window = MODEST_MSG_EDIT_WINDOW (userdata);
1770 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1771 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1773 if (gtk_check_menu_item_get_active (menu_item)) {
1775 WPTextBufferFormat format;
1777 memset (&format, 0, sizeof (format));
1778 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1780 label = gtk_bin_get_child (GTK_BIN (menu_item));
1782 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1783 format.cs.font_size = TRUE;
1784 format.cs.text_position = TRUE;
1785 format.cs.font = TRUE;
1786 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1787 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1789 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1790 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1791 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1793 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1794 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1795 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1801 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1804 ModestMsgEditWindowPrivate *priv;
1805 gint new_font_index;
1806 ModestMsgEditWindow *window;
1809 window = MODEST_MSG_EDIT_WINDOW (userdata);
1810 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1811 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1813 if (gtk_check_menu_item_get_active (menu_item)) {
1816 label = gtk_bin_get_child (GTK_BIN (menu_item));
1818 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1820 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1821 (gpointer) new_font_index))
1822 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1824 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1825 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1826 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1832 modest_msg_edit_window_set_zoom (ModestWindow *window,
1835 ModestMsgEditWindowPrivate *priv;
1836 ModestWindowPrivate *parent_priv;
1837 GtkRadioAction *zoom_radio_action;
1839 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1841 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1842 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1843 priv->zoom_level = zoom;
1844 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1846 /* Zoom level menu options should be updated with the current zoom level */
1847 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1848 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1849 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1850 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1854 modest_msg_edit_window_get_zoom (ModestWindow *window)
1856 ModestMsgEditWindowPrivate *priv;
1858 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1860 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1861 return priv->zoom_level;
1865 zoom_allowed (ModestMsgEditWindow *window)
1869 focus = gtk_window_get_focus (GTK_WINDOW (window));
1870 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1874 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1876 ModestWindowPrivate *parent_priv;
1877 GtkRadioAction *zoom_radio_action;
1878 GSList *group, *node;
1880 /* First we check if the text view is focused. If not, zooming is not allowed */
1881 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1882 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1886 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1887 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1888 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1890 group = gtk_radio_action_get_group (zoom_radio_action);
1892 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1893 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1897 for (node = group; node != NULL; node = g_slist_next (node)) {
1898 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1899 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1907 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1909 ModestWindowPrivate *parent_priv;
1910 GtkRadioAction *zoom_radio_action;
1911 GSList *group, *node;
1913 /* First we check if the text view is focused. If not, zooming is not allowed */
1914 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1915 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1919 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1920 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1921 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1923 group = gtk_radio_action_get_group (zoom_radio_action);
1925 for (node = group; node != NULL; node = g_slist_next (node)) {
1926 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1927 if (node->next != NULL) {
1928 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1931 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1939 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1941 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1942 ModestWindowPrivate *parent_priv;
1943 ModestWindowMgr *mgr;
1944 gboolean is_fullscreen;
1945 GtkAction *fs_toggle_action;
1948 mgr = modest_runtime_get_window_mgr ();
1949 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1951 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1953 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1954 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1955 if (is_fullscreen != active)
1956 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1964 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1966 ModestWindowPrivate *parent_priv;
1967 GtkAction *fs_toggle_action;
1970 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1972 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1973 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1974 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1978 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1981 ModestMsgEditWindowPrivate *priv = NULL;
1982 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1984 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1985 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1987 gtk_widget_show (priv->cc_caption);
1989 gtk_widget_hide (priv->cc_caption);
1990 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1994 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1997 ModestMsgEditWindowPrivate *priv = NULL;
1998 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2000 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2001 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2003 gtk_widget_show (priv->bcc_caption);
2005 gtk_widget_hide (priv->bcc_caption);
2006 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2010 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2011 ModestRecptEditor *editor)
2013 ModestMsgEditWindowPrivate *priv;
2015 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2016 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2017 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2019 if (editor == NULL) {
2020 GtkWidget *view_focus;
2021 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2023 /* This code should be kept in sync with ModestRecptEditor. The
2024 textview inside the recpt editor is the one that really gets the
2025 focus. As it's inside a scrolled window, and this one inside the
2026 hbox recpt editor inherits from, we'll need to go up in the
2027 hierarchy to know if the text view is part of the recpt editor
2028 or if it's a different text entry */
2030 if (gtk_widget_get_parent (view_focus)) {
2031 GtkWidget *first_parent;
2033 first_parent = gtk_widget_get_parent (view_focus);
2034 if (gtk_widget_get_parent (first_parent) &&
2035 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2036 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2041 editor = MODEST_RECPT_EDITOR (priv->to_field);
2045 modest_address_book_select_addresses (editor);
2050 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2052 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2054 modest_msg_edit_window_open_addressbook (window, NULL);
2058 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2059 gboolean show_toolbar)
2061 ModestWindowPrivate *parent_priv;
2063 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2064 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2066 /* FIXME: we can not just use the code of
2067 modest_msg_edit_window_setup_toolbar because it has a
2068 mixture of both initialization and creation code. */
2071 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2073 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2077 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2078 TnyHeaderFlags priority_flags)
2080 ModestMsgEditWindowPrivate *priv;
2081 ModestWindowPrivate *parent_priv;
2083 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2085 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2086 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2087 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2089 if (priv->priority_flags != priority_flags) {
2090 GtkAction *priority_action = NULL;
2092 priv->priority_flags = priority_flags;
2094 switch (priority_flags) {
2095 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2096 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2097 gtk_widget_show (priv->priority_icon);
2098 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2099 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2101 case TNY_HEADER_FLAG_LOW_PRIORITY:
2102 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2103 gtk_widget_show (priv->priority_icon);
2104 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2105 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2108 gtk_widget_hide (priv->priority_icon);
2109 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2110 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2113 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2114 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2119 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2122 ModestMsgEditWindowPrivate *priv;
2123 gint current_format;
2125 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2127 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2129 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2130 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2132 if (current_format != file_format) {
2133 switch (file_format) {
2134 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2135 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2137 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2141 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2142 response = gtk_dialog_run (GTK_DIALOG (dialog));
2143 gtk_widget_destroy (dialog);
2144 if (response == GTK_RESPONSE_OK)
2145 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2149 update_dimmed (window);
2154 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2157 ModestMsgEditWindowPrivate *priv;
2158 WPTextBufferFormat oldfmt, fmt;
2159 gint old_position = 0;
2163 GdkColor *color = NULL;
2164 gboolean bold, bold_set, italic, italic_set;
2165 gboolean underline, underline_set;
2166 gboolean strikethrough, strikethrough_set;
2167 gboolean position_set;
2168 gboolean font_size_set, font_set, color_set;
2171 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2172 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2174 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2176 /* First we get the currently selected font information */
2177 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2178 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2180 switch (oldfmt.text_position) {
2181 case TEXT_POSITION_NORMAL:
2184 case TEXT_POSITION_SUPERSCRIPT:
2192 g_object_set (G_OBJECT (dialog),
2193 "bold", oldfmt.bold != FALSE,
2194 "bold-set", !oldfmt.cs.bold,
2195 "underline", oldfmt.underline != FALSE,
2196 "underline-set", !oldfmt.cs.underline,
2197 "italic", oldfmt.italic != FALSE,
2198 "italic-set", !oldfmt.cs.italic,
2199 "strikethrough", oldfmt.strikethrough != FALSE,
2200 "strikethrough-set", !oldfmt.cs.strikethrough,
2201 "color", &oldfmt.color,
2202 "color-set", !oldfmt.cs.color,
2203 "size", wp_font_size[oldfmt.font_size],
2204 "size-set", !oldfmt.cs.font_size,
2205 "position", old_position,
2206 "position-set", !oldfmt.cs.text_position,
2207 "family", wp_get_font_name (oldfmt.font),
2208 "family-set", !oldfmt.cs.font,
2211 gtk_widget_show_all (dialog);
2212 response = gtk_dialog_run (GTK_DIALOG (dialog));
2213 if (response == GTK_RESPONSE_OK) {
2215 g_object_get( dialog,
2217 "bold-set", &bold_set,
2218 "underline", &underline,
2219 "underline-set", &underline_set,
2221 "italic-set", &italic_set,
2222 "strikethrough", &strikethrough,
2223 "strikethrough-set", &strikethrough_set,
2225 "color-set", &color_set,
2227 "size-set", &font_size_set,
2228 "family", &font_name,
2229 "family-set", &font_set,
2230 "position", &position,
2231 "position-set", &position_set,
2236 if (response == GTK_RESPONSE_OK) {
2237 memset(&fmt, 0, sizeof(fmt));
2243 fmt.italic = italic;
2244 fmt.cs.italic = TRUE;
2246 if (underline_set) {
2247 fmt.underline = underline;
2248 fmt.cs.underline = TRUE;
2250 if (strikethrough_set) {
2251 fmt.strikethrough = strikethrough;
2252 fmt.cs.strikethrough = TRUE;
2257 ? TEXT_POSITION_NORMAL
2258 : ( ( position == 1 )
2259 ? TEXT_POSITION_SUPERSCRIPT
2260 : TEXT_POSITION_SUBSCRIPT );
2261 fmt.cs.text_position = TRUE;
2265 fmt.cs.color = TRUE;
2268 fmt.font = wp_get_font_index(font_name,
2273 if (font_size_set) {
2274 fmt.font_size = wp_get_font_size_index(
2275 font_size, DEFAULT_FONT_SIZE);
2276 fmt.cs.font_size = TRUE;
2278 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2280 gtk_widget_destroy (dialog);
2282 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2286 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2288 ModestMsgEditWindowPrivate *priv;
2290 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2291 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2293 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2295 update_dimmed (window);
2300 update_dimmed (ModestMsgEditWindow *window)
2302 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2303 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2307 gboolean editor_focused;
2309 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2310 editor_focused = gtk_widget_is_focus (priv->msg_body);
2312 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2313 gtk_action_set_sensitive (action, rich_text && editor_focused);
2314 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2315 gtk_action_set_sensitive (action, rich_text && editor_focused);
2316 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2317 gtk_action_set_sensitive (action, rich_text && editor_focused);
2318 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2319 gtk_action_set_sensitive (action, rich_text && editor_focused);
2320 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2321 gtk_action_set_sensitive (action, rich_text && editor_focused);
2322 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2323 gtk_action_set_sensitive (action, rich_text && editor_focused);
2324 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2325 gtk_action_set_sensitive (action, rich_text && editor_focused);
2326 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2327 gtk_action_set_sensitive (action, rich_text && editor_focused);
2328 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2329 gtk_action_set_sensitive (action, rich_text && editor_focused);
2330 widget = priv->font_color_button;
2331 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2332 widget = priv->font_size_toolitem;
2333 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2334 widget = priv->font_face_toolitem;
2335 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2339 setup_insensitive_handlers (ModestMsgEditWindow *window)
2341 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2342 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2345 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2346 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2347 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2348 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2350 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2351 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2352 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2353 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2354 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2355 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2356 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2357 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2358 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2359 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2360 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2361 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2362 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2363 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2364 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2365 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2366 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2367 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2368 widget = priv->font_color_button;
2369 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2370 widget = priv->font_size_toolitem;
2371 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2372 widget = priv->font_face_toolitem;
2373 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2375 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2376 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (remove_attachment_insensitive_press), window);
2377 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2378 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (zoom_insensitive_press), window);
2382 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2384 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2387 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2388 gtk_action_set_sensitive (action, can_undo);
2392 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2395 GtkTextIter match_start, match_end;
2397 if (image_id == NULL)
2400 gtk_text_buffer_get_start_iter (buffer, &iter);
2402 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2403 GSList *tags = gtk_text_iter_get_tags (&match_start);
2405 for (node = tags; node != NULL; node = g_slist_next (node)) {
2406 GtkTextTag *tag = (GtkTextTag *) node->data;
2407 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2408 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2409 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2411 offset = gtk_text_iter_get_offset (&match_start);
2412 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2413 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2417 gtk_text_iter_forward_char (&iter);
2422 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2424 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2425 GtkTextIter real_start, real_end;
2426 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2428 if (gtk_text_iter_compare (start, end) > 0) {
2432 real_start = *start;
2436 GSList *tags = gtk_text_iter_get_tags (&real_start);
2438 for (node = tags; node != NULL; node = g_slist_next (node)) {
2439 GtkTextTag *tag = (GtkTextTag *) node->data;
2440 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2441 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2443 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2445 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2448 } while (gtk_text_iter_forward_char (&real_start)&&
2449 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2453 msg_body_focus (GtkWidget *focus,
2454 GdkEventFocus *event,
2458 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2463 recpt_field_changed (GtkTextBuffer *buffer,
2464 ModestMsgEditWindow *editor)
2466 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2467 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2468 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2469 gboolean dim = FALSE;
2472 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2473 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2474 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2476 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2477 gtk_text_buffer_get_char_count (cc_buffer) +
2478 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2480 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2481 gtk_action_set_sensitive (action, !dim);
2482 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2483 gtk_action_set_sensitive (action, !dim);
2487 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2489 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2493 zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2495 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2499 remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2501 ModestWindowPrivate *parent_priv;
2502 ModestMsgEditWindowPrivate *priv;
2503 GList *selected_attachments = NULL;
2504 gint n_att_selected = 0;
2506 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2507 parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2509 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2510 n_att_selected = g_list_length (selected_attachments);
2511 g_list_free (selected_attachments);
2513 if (n_att_selected > 1)
2514 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
2515 else if (n_att_selected == 0)
2516 hildon_banner_show_information (NULL, NULL, _("TODO: select one attachment"));
2521 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2523 gboolean rich_text, editor_focused;
2525 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2526 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2527 editor_focused = gtk_widget_is_focus (priv->msg_body);
2530 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2531 else if (!editor_focused)
2532 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2536 reset_modified (ModestMsgEditWindow *editor)
2538 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2539 GtkTextBuffer *buffer;
2541 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2542 gtk_text_buffer_set_modified (buffer, FALSE);
2543 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2544 gtk_text_buffer_set_modified (buffer, FALSE);
2545 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2546 gtk_text_buffer_set_modified (buffer, FALSE);
2547 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2551 is_modified (ModestMsgEditWindow *editor)
2553 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2554 GtkTextBuffer *buffer;
2556 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2557 if (gtk_text_buffer_get_modified (buffer))
2559 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2560 if (gtk_text_buffer_get_modified (buffer))
2562 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2563 if (gtk_text_buffer_get_modified (buffer))
2565 if (gtk_text_buffer_get_modified (priv->text_buffer))
2572 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2574 ModestMsgEditWindowPrivate *priv = NULL;
2576 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2577 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2579 /* check if there's no recipient added */
2580 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2581 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2582 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2583 /* no recipient contents, then select contacts */
2584 modest_msg_edit_window_open_addressbook (window, NULL);
2588 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2590 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2592 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2595 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2602 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2603 ModestMsgEditWindow *window)
2605 modest_msg_edit_window_attach_file (window);
2609 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2611 ModestMsgEditWindow *window)
2613 ModestWindowPrivate *parent_priv;
2614 ModestMsgEditWindowPrivate *priv;
2618 GList *selected_attachments = NULL;
2619 gint n_att_selected = 0;
2621 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2622 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2623 selection = gtk_clipboard_wait_for_text (clipboard);
2624 focused = gtk_window_get_focus (GTK_WINDOW (window));
2626 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2627 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2628 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2629 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2631 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2632 n_att_selected = g_list_length (selected_attachments);
2633 g_list_free (selected_attachments);
2635 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2636 gtk_action_set_sensitive (action, n_att_selected == 1);
2639 update_paste_dimming (window);
2643 update_window_title (ModestMsgEditWindow *window)
2645 ModestMsgEditWindowPrivate *priv = NULL;
2646 const gchar *subject;
2648 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2649 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2650 if (subject == NULL || subject[0] == '\0')
2651 subject = _("mail_va_new_email");
2653 gtk_window_set_title (GTK_WINDOW (window), subject);
2658 subject_field_changed (GtkEditable *editable,
2659 ModestMsgEditWindow *window)
2661 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2662 update_window_title (window);
2663 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2667 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2670 ModestMsgEditWindowPrivate *priv = NULL;
2672 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2673 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2675 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2677 gtk_widget_show_all (priv->find_toolbar);
2678 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2680 gtk_widget_hide_all (priv->find_toolbar);
2681 gtk_widget_grab_focus (priv->msg_body);
2687 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2688 ModestMsgEditWindow *window)
2690 gchar *current_search = NULL;
2691 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2693 GtkTextIter selection_start, selection_end;
2694 GtkTextIter match_start, match_end;
2696 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2697 if ((current_search == NULL) && (strcmp (current_search, "") == 0)) {
2698 g_free (current_search);
2702 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2703 result = gtk_text_iter_forward_search (&selection_end, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, NULL);
2705 GtkTextIter buffer_start;
2706 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2707 result = gtk_text_iter_forward_search (&buffer_start, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, &selection_start);
2710 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2711 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2713 /* TODO: warning about non succesful search */
2715 g_free (current_search);
2719 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2720 ModestMsgEditWindow *window)
2722 GtkToggleAction *toggle;
2723 ModestWindowPrivate *parent_priv;
2724 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2726 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2727 gtk_toggle_action_set_active (toggle, FALSE);
2732 update_paste_dimming (ModestMsgEditWindow *window)
2734 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2735 GtkAction *action = NULL;
2736 GtkClipboard *clipboard = NULL;
2738 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2740 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2741 gtk_action_set_sensitive (action, gtk_clipboard_wait_is_text_available (clipboard));
2746 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2748 ModestMsgEditWindow *window)
2750 update_paste_dimming (window);
2754 update_select_all_dimming (ModestMsgEditWindow *window)
2757 gboolean dimmed = FALSE;
2759 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2761 focused = gtk_window_get_focus (GTK_WINDOW (window));
2762 if (GTK_IS_ENTRY (focused)) {
2763 const gchar *current_text;
2764 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2765 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2766 } else if (GTK_IS_TEXT_VIEW (focused)) {
2767 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2768 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2769 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2772 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2773 gtk_action_set_sensitive (action, !dimmed);
2777 update_zoom_dimming (ModestMsgEditWindow *window)
2780 gboolean dimmed = FALSE;
2782 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2784 focused = gtk_window_get_focus (GTK_WINDOW (window));
2785 dimmed = ! WP_IS_TEXT_VIEW (focused);
2786 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2787 gtk_action_set_sensitive (action, !dimmed);
2791 edit_menu_activated (GtkAction *action,
2794 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2796 update_select_all_dimming (window);
2799 view_menu_activated (GtkAction *action,
2802 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2804 update_zoom_dimming (window);