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 *scroll_area;
347 GtkWidget *subject_box;
348 GtkWidget *attachment_icon;
349 GtkWidget *window_box;
351 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
353 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
355 /* Note: This ModestPairList* must exist for as long as the combo
356 * that uses it, because the ModestComboBox uses the ID opaquely,
357 * so it can't know how to manage its memory. */
358 priv->from_field_protos = get_transports ();
360 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
362 priv->to_field = modest_recpt_editor_new ();
363 priv->cc_field = modest_recpt_editor_new ();
364 priv->bcc_field = modest_recpt_editor_new ();
365 subject_box = gtk_hbox_new (FALSE, 0);
366 priv->priority_icon = gtk_image_new ();
367 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
368 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
369 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
370 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
371 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
372 priv->add_attachment_button = gtk_button_new ();
373 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
374 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
375 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
376 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
377 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
378 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
379 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
380 priv->attachments_view = modest_attachments_view_new (NULL);
382 priv->header_box = gtk_vbox_new (FALSE, 0);
384 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
385 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
386 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
387 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
388 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
389 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
390 g_object_unref (size_group);
392 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
393 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
394 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
395 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
396 gtk_size_group_add_widget (size_group, priv->subject_field);
397 gtk_size_group_add_widget (size_group, priv->attachments_view);
398 g_object_unref (size_group);
400 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
401 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
402 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
403 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
404 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
405 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
406 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
409 priv->msg_body = wp_text_view_new ();
410 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
411 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
412 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
413 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
414 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
415 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
417 priv->find_toolbar = hildon_find_toolbar_new (NULL);
418 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
420 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
421 G_CALLBACK (text_buffer_refresh_attributes), obj);
422 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
423 G_CALLBACK (text_buffer_delete_range), obj);
424 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
425 G_CALLBACK (text_buffer_can_undo), obj);
426 g_signal_connect (G_OBJECT (obj), "window-state-event",
427 G_CALLBACK (modest_msg_edit_window_window_state_event),
429 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
430 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
431 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
432 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
433 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
434 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
436 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
437 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
439 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
440 G_CALLBACK (msg_body_focus), obj);
441 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
442 G_CALLBACK (msg_body_focus), obj);
443 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
444 "changed", G_CALLBACK (recpt_field_changed), obj);
445 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
446 "changed", G_CALLBACK (recpt_field_changed), obj);
447 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
448 "changed", G_CALLBACK (recpt_field_changed), obj);
449 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
450 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
452 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
453 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
455 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
456 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
457 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
459 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
461 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
462 frame = gtk_frame_new (NULL);
463 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
465 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
466 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
467 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
469 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
470 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
471 gtk_widget_hide (priv->cc_caption);
473 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
474 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
475 gtk_widget_hide (priv->bcc_caption);
478 window_box = gtk_vbox_new (FALSE, 0);
479 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
480 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
481 gtk_container_add (GTK_CONTAINER(obj), window_box);
482 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
483 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
484 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
485 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
487 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
488 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
489 priv->system_clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
490 G_CALLBACK (modest_msg_edit_window_system_clipboard_owner_change), obj);
496 modest_msg_edit_window_finalize (GObject *obj)
498 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
500 if (priv->clipboard_change_handler_id > 0) {
501 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
502 priv->clipboard_change_handler_id = 0;
505 if (priv->system_clipboard_change_handler_id > 0) {
506 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
507 priv->system_clipboard_change_handler_id);
508 priv->system_clipboard_change_handler_id = 0;
511 /* This had to stay alive for as long as the combobox that used it: */
512 modest_pair_list_free (priv->from_field_protos);
514 G_OBJECT_CLASS(parent_class)->finalize (obj);
518 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
520 GtkWidget *close_dialog;
521 ModestMsgEditWindowPrivate *priv;
524 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
525 modest_window_save_state (MODEST_WINDOW (self));
526 if (is_modified (self)) {
527 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
528 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
529 gtk_widget_destroy (close_dialog);
531 if (response != GTK_RESPONSE_CANCEL) {
532 modest_ui_actions_on_save_to_drafts (NULL, self);
535 /* /\* remove old message from drafts *\/ */
536 /* if (priv->draft_msg) { */
537 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
538 /* TnyAccount *account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(), */
540 /* TNY_ACCOUNT_TYPE_STORE); */
541 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
542 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
543 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
544 /* tny_folder_remove_msg (folder, header, NULL); */
545 /* g_object_unref (folder); */
546 /* g_object_unref (header); */
547 /* g_object_unref (priv->draft_msg); */
548 /* priv->draft_msg = NULL; */
550 gtk_widget_destroy (GTK_WIDGET (self));
556 menubar_to_menu (GtkUIManager *ui_manager)
558 GtkWidget *main_menu;
562 /* Create new main menu */
563 main_menu = gtk_menu_new();
565 /* Get the menubar from the UI manager */
566 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
568 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
572 menu = GTK_WIDGET (iter->data);
573 gtk_widget_reparent(menu, main_menu);
575 iter = g_list_next (iter);
582 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
585 const gchar *to, *cc, *bcc, *subject;
587 ModestMsgEditWindowPrivate *priv;
589 TnyHeaderFlags priority_flags;
591 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
592 g_return_if_fail (TNY_IS_MSG (msg));
594 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
596 header = tny_msg_get_header (msg);
597 to = tny_header_get_to (header);
598 cc = tny_header_get_cc (header);
599 bcc = tny_header_get_bcc (header);
600 subject = tny_header_get_subject (header);
601 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
604 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
606 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
608 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
610 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
611 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
614 update_window_title (self);
616 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
617 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
618 body = modest_tny_msg_get_body (msg, TRUE);
620 if ((body == NULL)||(body[0] == '\0')) {
622 body = modest_text_utils_convert_to_html ("");
624 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
625 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
628 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
631 /* Get the default format required from configuration */
632 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
633 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
636 /* Set the default focus depending on having already a To: field or not */
637 if ((!to)||(*to == '\0')) {
638 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
640 gtk_widget_grab_focus (priv->msg_body);
643 /* TODO: lower priority, select in the From: combo to the
644 value that comes from msg <- not sure, should it be
647 /* Add attachments to the view */
648 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
649 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
650 if (priv->attachments == NULL) {
651 gtk_widget_hide (priv->attachments_caption);
653 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
654 gtk_widget_show_all (priv->attachments_caption);
657 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
658 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
660 reset_modified (self);
662 update_dimmed (self);
663 text_buffer_can_undo (priv->text_buffer, FALSE, self);
665 priv->draft_msg = msg;
669 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
672 GList *item_children, *node;
673 GtkWidget *bin_child;
675 bin_child = gtk_bin_get_child (GTK_BIN(item));
677 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
679 for (node = item_children; node != NULL; node = g_list_next (node)) {
680 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
681 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
684 g_list_free (item_children);
688 menu_tool_button_dont_expand (GtkMenuToolButton *item)
691 GList *item_children, *node;
693 box = gtk_bin_get_child (GTK_BIN (item));
694 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
695 item_children = gtk_container_get_children (GTK_CONTAINER (box));
697 for (node = item_children; node != NULL; node = g_list_next (node)) {
698 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
699 if (GTK_IS_TOGGLE_BUTTON (node->data))
700 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
701 else if (GTK_IS_BUTTON (node->data))
702 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
704 g_list_free (item_children);
709 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
711 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
712 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
713 GtkWidget *placeholder;
714 GtkWidget *tool_item;
719 GtkWidget *sizes_menu;
720 GtkWidget *fonts_menu;
721 GSList *radio_group = NULL;
726 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
727 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
729 /* should we hide the toolbar? */
730 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
731 gtk_widget_hide (parent_priv->toolbar);
733 /* Font color placeholder */
734 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
735 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
738 tool_item = GTK_WIDGET (gtk_tool_item_new ());
739 priv->font_color_button = hildon_color_button_new ();
740 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
741 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
742 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
743 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
744 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
745 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
746 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
748 /* Font size and face placeholder */
749 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
750 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
752 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
753 priv->size_tool_button_label = gtk_label_new (NULL);
754 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
755 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
756 size_text,"</span>", NULL);
757 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
759 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
760 sizes_menu = gtk_menu_new ();
761 priv->size_items_group = NULL;
763 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
764 GtkWidget *size_menu_item;
766 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
767 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
768 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
769 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
770 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
771 gtk_widget_show (size_menu_item);
773 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
777 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
778 GtkWidget *item = (GtkWidget *) node->data;
779 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
783 priv->size_items_group = g_slist_reverse (priv->size_items_group);
784 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
785 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
786 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
787 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
788 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
789 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
790 priv->font_size_toolitem = tool_item;
793 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
794 priv->font_tool_button_label = gtk_label_new (NULL);
795 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
796 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
798 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
799 fonts_menu = gtk_menu_new ();
800 priv->font_items_group = NULL;
802 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
803 GtkWidget *font_menu_item;
804 GtkWidget *child_label;
806 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
807 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
808 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
809 wp_get_font_name (font_index), "</span>", NULL);
810 gtk_label_set_markup (GTK_LABEL (child_label), markup);
813 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
814 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
815 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
816 gtk_widget_show (font_menu_item);
818 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
821 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
822 GtkWidget *item = (GtkWidget *) node->data;
823 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
826 priv->font_items_group = g_slist_reverse (priv->font_items_group);
827 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
828 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
829 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
830 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
831 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
832 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
833 priv->font_face_toolitem = tool_item;
835 /* Set expand and homogeneous for remaining items */
836 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
837 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
838 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
839 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
840 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
841 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
842 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
843 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
844 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
852 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
855 ModestWindowPrivate *parent_priv;
856 ModestMsgEditWindowPrivate *priv;
857 GtkActionGroup *action_group;
858 GError *error = NULL;
859 GdkPixbuf *window_icon = NULL;
862 gboolean prefer_formatted;
864 ModestPair *account_pair = NULL;
866 g_return_val_if_fail (msg, NULL);
867 g_return_val_if_fail (account_name, NULL);
869 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
871 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
872 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
874 parent_priv->ui_manager = gtk_ui_manager_new();
875 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
876 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
878 /* Add common actions */
879 gtk_action_group_add_actions (action_group,
880 modest_msg_edit_action_entries,
881 G_N_ELEMENTS (modest_msg_edit_action_entries),
883 gtk_action_group_add_toggle_actions (action_group,
884 modest_msg_edit_toggle_action_entries,
885 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
887 gtk_action_group_add_radio_actions (action_group,
888 modest_msg_edit_alignment_radio_action_entries,
889 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
891 G_CALLBACK (modest_ui_actions_on_change_justify),
893 gtk_action_group_add_radio_actions (action_group,
894 modest_msg_edit_zoom_action_entries,
895 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
897 G_CALLBACK (modest_ui_actions_on_change_zoom),
899 gtk_action_group_add_radio_actions (action_group,
900 modest_msg_edit_priority_action_entries,
901 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
903 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
905 gtk_action_group_add_radio_actions (action_group,
906 modest_msg_edit_file_format_action_entries,
907 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
908 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
909 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
911 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
912 g_object_unref (action_group);
914 /* Load the UI definition */
915 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
918 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
919 g_clear_error (&error);
922 /* Add accelerators */
923 gtk_window_add_accel_group (GTK_WINDOW (obj),
924 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
927 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
928 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
931 init_window (MODEST_MSG_EDIT_WINDOW(obj));
933 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
935 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
937 g_signal_connect (G_OBJECT(obj), "delete-event",
938 G_CALLBACK(on_delete_event), obj);
940 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
942 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
944 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
946 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
947 if (account_pair != NULL)
948 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
950 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
952 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
954 /* Set window icon */
955 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
956 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
958 /* Dim at start clipboard actions */
959 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
960 gtk_action_set_sensitive (action, FALSE);
961 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
962 gtk_action_set_sensitive (action, FALSE);
963 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
964 gtk_action_set_sensitive (action, FALSE);
966 /* Update select all */
967 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
968 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
969 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
970 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
971 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
973 /* set initial state of cc and bcc */
974 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
975 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
976 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
977 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
978 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
979 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
981 /* Setup the file format */
982 conf = modest_runtime_get_conf ();
983 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
985 g_clear_error (&error);
986 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
988 file_format = (prefer_formatted) ?
989 MODEST_FILE_FORMAT_FORMATTED_TEXT :
990 MODEST_FILE_FORMAT_PLAIN_TEXT;
991 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
993 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
995 return (ModestWindow*) obj;
999 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1001 GString **string_buffer = (GString **) user_data;
1003 *string_buffer = g_string_append (*string_buffer, buffer);
1009 * @result: A new string which should be freed with g_free().
1012 get_formatted_data (ModestMsgEditWindow *edit_window)
1014 ModestMsgEditWindowPrivate *priv;
1015 GString *string_buffer = g_string_new ("");
1017 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1019 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1021 return g_string_free (string_buffer, FALSE);
1026 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1029 const gchar *account_name;
1030 ModestMsgEditWindowPrivate *priv;
1032 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1034 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1036 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1037 g_return_val_if_fail (account_name, NULL);
1040 /* don't free these (except from) */
1041 data = g_slice_new0 (MsgData);
1042 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1044 data->account_name = g_strdup (account_name);
1045 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1046 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1047 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1048 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1049 if (priv->draft_msg) {
1050 data->draft_msg = g_object_ref (priv->draft_msg);
1052 data->draft_msg = NULL;
1055 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1057 gtk_text_buffer_get_bounds (buf, &b, &e);
1058 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1060 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1061 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1063 data->html_body = NULL;
1065 data->attachments = priv->attachments; /* TODO: copy and free ? */
1066 data->priority_flags = priv->priority_flags;
1071 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1073 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1076 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1084 g_free (data->subject);
1085 g_free (data->plain_body);
1086 g_free (data->html_body);
1087 if (data->draft_msg != NULL) {
1088 g_object_unref (data->draft_msg);
1089 data->draft_msg = NULL;
1091 g_free (data->account_name);
1093 /* TODO: Free data->attachments? */
1095 g_slice_free (MsgData, data);
1099 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1102 ModestMsgEditWindowPrivate *priv = NULL;
1103 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1105 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1107 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1109 return MODEST_MSG_EDIT_FORMAT_HTML;
1111 return MODEST_MSG_EDIT_FORMAT_TEXT;
1115 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1116 ModestMsgEditFormat format)
1118 ModestMsgEditWindowPrivate *priv;
1120 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1121 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1124 case MODEST_MSG_EDIT_FORMAT_HTML:
1125 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1127 case MODEST_MSG_EDIT_FORMAT_TEXT:
1128 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1131 g_return_if_reached ();
1135 ModestMsgEditFormatState *
1136 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1138 ModestMsgEditFormatState *format_state = NULL;
1139 ModestMsgEditWindowPrivate *priv;
1140 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1142 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1143 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1145 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1147 format_state = g_new0 (ModestMsgEditFormatState, 1);
1148 format_state->bold = buffer_format->bold&0x1;
1149 format_state->italics = buffer_format->italic&0x1;
1150 format_state->bullet = buffer_format->bullet&0x1;
1151 format_state->color = buffer_format->color;
1152 format_state->font_size = buffer_format->font_size;
1153 format_state->font_family = wp_get_font_name (buffer_format->font);
1154 format_state->justification = buffer_format->justification;
1155 g_free (buffer_format);
1157 return format_state;
1162 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1163 const ModestMsgEditFormatState *format_state)
1165 ModestMsgEditWindowPrivate *priv;
1166 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1167 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1168 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1169 g_return_if_fail (format_state != NULL);
1171 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1172 gtk_widget_grab_focus (priv->msg_body);
1173 buffer_format->bold = (format_state->bold != FALSE);
1174 buffer_format->italic = (format_state->italics != FALSE);
1175 buffer_format->color = format_state->color;
1176 buffer_format->font_size = format_state->font_size;
1177 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1178 buffer_format->justification = format_state->justification;
1179 buffer_format->bullet = format_state->bullet;
1181 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1183 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1184 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1185 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1186 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1187 buffer_format->cs.font = (buffer_format->font != current_format->font);
1188 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1189 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1191 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1192 if (buffer_format->cs.bold) {
1193 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1195 if (buffer_format->cs.italic) {
1196 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1198 if (buffer_format->cs.color) {
1199 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1201 if (buffer_format->cs.font_size) {
1202 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1204 if (buffer_format->cs.justification) {
1205 switch (buffer_format->justification) {
1206 case GTK_JUSTIFY_LEFT:
1207 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1209 case GTK_JUSTIFY_CENTER:
1210 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1212 case GTK_JUSTIFY_RIGHT:
1213 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1220 if (buffer_format->cs.font) {
1221 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1223 if (buffer_format->cs.bullet) {
1224 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1226 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1227 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1229 g_free (current_format);
1234 toggle_action_set_active_block_notify (GtkToggleAction *action,
1237 GSList *proxies = NULL;
1239 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1240 proxies != NULL; proxies = g_slist_next (proxies)) {
1241 GtkWidget *widget = (GtkWidget *) proxies->data;
1242 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1245 gtk_toggle_action_set_active (action, value);
1247 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1248 proxies != NULL; proxies = g_slist_next (proxies)) {
1249 GtkWidget *widget = (GtkWidget *) proxies->data;
1250 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1255 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1257 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1259 ModestWindowPrivate *parent_priv;
1260 ModestMsgEditWindowPrivate *priv;
1261 GtkWidget *new_size_menuitem;
1262 GtkWidget *new_font_menuitem;
1264 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1265 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1267 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1268 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1269 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1270 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1272 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1273 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1274 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1277 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1279 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1280 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1282 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1283 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1285 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1286 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1288 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1289 G_CALLBACK (modest_msg_edit_window_color_button_change),
1291 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1292 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1293 G_CALLBACK (modest_msg_edit_window_color_button_change),
1296 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1297 buffer_format->font_size))->data);
1298 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1302 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1303 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1304 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1306 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1307 G_CALLBACK (modest_msg_edit_window_size_change),
1309 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1310 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1311 G_CALLBACK (modest_msg_edit_window_size_change),
1315 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1316 buffer_format->font))->data);
1317 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1321 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1322 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1323 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1325 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1326 G_CALLBACK (modest_msg_edit_window_font_change),
1328 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1329 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1330 G_CALLBACK (modest_msg_edit_window_font_change),
1334 g_free (buffer_format);
1340 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1343 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1344 ModestMsgEditWindowPrivate *priv;
1345 GtkWidget *dialog = NULL;
1347 const GdkColor *new_color = NULL;
1349 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1350 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1352 #ifdef MODEST_HILDON_VERSION_0
1353 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1354 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1356 dialog = hildon_color_chooser_new ();
1357 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1358 #endif /*MODEST_HILDON_VERSION_0*/
1359 g_free (buffer_format);
1361 response = gtk_dialog_run (GTK_DIALOG (dialog));
1363 case GTK_RESPONSE_OK: {
1364 #ifdef MODEST_HILDON_VERSION_0
1365 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1368 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1370 #endif /*MODEST_HILDON_VERSION_0*/
1377 gtk_widget_destroy (dialog);
1379 if (new_color != NULL)
1380 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1385 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1388 ModestMsgEditWindowPrivate *priv;
1389 GtkWidget *dialog = NULL;
1391 GdkColor *old_color = NULL;
1392 const GdkColor *new_color = NULL;
1394 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1395 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1397 #ifdef MODEST_HILDON_VERSION_0
1398 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1399 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1401 dialog = hildon_color_chooser_new ();
1402 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1403 #endif /*MODEST_HILDON_VERSION_9*/
1405 response = gtk_dialog_run (GTK_DIALOG (dialog));
1407 case GTK_RESPONSE_OK: {
1408 #ifdef MODEST_HILDON_VERSION_0
1409 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1412 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1414 #endif /*MODEST_HILDON_VERSION_0*/
1420 gtk_widget_destroy (dialog);
1422 if (new_color != NULL)
1423 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1429 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1432 ModestMsgEditWindowPrivate *priv;
1433 GtkWidget *dialog = NULL;
1435 GSList *uris = NULL;
1436 GSList *uri_node = NULL;
1438 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1440 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1441 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1442 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1444 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1446 response = gtk_dialog_run (GTK_DIALOG (dialog));
1448 case GTK_RESPONSE_OK:
1449 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1454 gtk_widget_destroy (dialog);
1456 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1458 GnomeVFSHandle *handle = NULL;
1459 GnomeVFSResult result;
1460 GtkTextIter position;
1461 GtkTextMark *insert_mark;
1463 uri = (const gchar *) uri_node->data;
1464 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1465 if (result == GNOME_VFS_OK) {
1466 GdkPixbufLoader *loader;
1468 GnomeVFSFileInfo info;
1469 gchar *filename, *basename;
1470 TnyMimePart *mime_part;
1473 const gchar *mime_type = NULL;
1475 filename = g_filename_from_uri (uri, NULL, NULL);
1476 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1478 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1480 mime_part = tny_platform_factory_new_mime_part
1481 (modest_runtime_get_platform_factory ());
1482 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1484 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1486 content_id = g_strdup_printf ("%d", priv->last_cid);
1487 tny_mime_part_set_content_id (mime_part, content_id);
1488 g_free (content_id);
1491 basename = g_path_get_basename (filename);
1492 tny_mime_part_set_filename (mime_part, basename);
1495 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1496 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1498 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1499 gtk_widget_show_all (priv->attachments_caption);
1500 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1503 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1504 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1505 char read_buffer[128];
1507 readed = tny_stream_read (TNY_STREAM (stream), read_buffer, 128);
1508 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1511 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1512 g_object_ref (pixbuf);
1513 gdk_pixbuf_loader_close (loader, NULL);
1514 g_object_unref (loader);
1516 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1517 GdkPixbuf *new_pixbuf;
1519 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1520 gdk_pixbuf_get_width (pixbuf);
1521 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1522 g_object_unref (pixbuf);
1523 pixbuf = new_pixbuf;
1526 if (pixbuf != NULL) {
1527 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1528 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1529 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1538 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1541 ModestMsgEditWindowPrivate *priv;
1542 GtkWidget *dialog = NULL;
1544 GSList *uris = NULL;
1547 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1549 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1550 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1552 response = gtk_dialog_run (GTK_DIALOG (dialog));
1554 case GTK_RESPONSE_OK:
1555 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1560 gtk_widget_destroy (dialog);
1562 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1564 GnomeVFSHandle *handle = NULL;
1565 GnomeVFSResult result;
1567 uri = (const gchar *) uri_node->data;
1568 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1569 if (result == GNOME_VFS_OK) {
1570 TnyMimePart *mime_part;
1572 const gchar *mime_type = NULL;
1576 GnomeVFSFileInfo info;
1578 filename = g_filename_from_uri (uri, NULL, NULL);
1580 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1581 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1582 mime_part = tny_platform_factory_new_mime_part
1583 (modest_runtime_get_platform_factory ());
1584 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1586 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1588 content_id = g_strdup_printf ("%d", priv->last_cid);
1589 tny_mime_part_set_content_id (mime_part, content_id);
1590 g_free (content_id);
1593 basename = g_path_get_basename (filename);
1594 tny_mime_part_set_filename (mime_part, basename);
1597 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1598 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1600 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1601 gtk_widget_show_all (priv->attachments_caption);
1602 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1607 g_slist_foreach (uris, (GFunc) g_free, NULL);
1608 g_slist_free (uris);
1612 modest_msg_edit_window_attach_file_noninteractive (
1613 ModestMsgEditWindow *window,
1614 const gchar *file_uri)
1617 ModestMsgEditWindowPrivate *priv;
1619 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1624 /* TODO: We should probably try to use only the URI,
1625 * instead of using a filename.
1627 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1629 g_warning("%s: g_filename_from_uri(%s) failed.\n", __FUNCTION__, file_uri);
1632 file_id = g_open (filename, O_RDONLY, 0);
1633 if (file_id != -1) {
1634 TnyMimePart *mime_part;
1636 const gchar *mime_type;
1640 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1641 mime_part = tny_platform_factory_new_mime_part
1642 (modest_runtime_get_platform_factory ());
1643 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1645 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1647 content_id = g_strdup_printf ("%d", priv->last_cid);
1648 tny_mime_part_set_content_id (mime_part, content_id);
1649 g_free (content_id);
1652 basename = g_path_get_basename (filename);
1653 tny_mime_part_set_filename (mime_part, basename);
1656 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1657 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1659 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1660 gtk_widget_show_all (priv->attachments_caption);
1661 } else if (file_id == -1) {
1663 g_warning("file to be attached does not exist: %s", filename);
1671 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1674 ModestMsgEditWindowPrivate *priv;
1675 gboolean clean_list = FALSE;
1677 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1678 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1680 if (att_list == NULL) {
1681 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1685 if (att_list == NULL) {
1686 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1688 GtkWidget *confirmation_dialog = NULL;
1689 gboolean dialog_response;
1691 gchar *message = NULL;
1692 const gchar *filename = NULL;
1694 if (att_list->next == NULL) {
1695 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1699 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1700 att_list->next == NULL), filename);
1701 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1703 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1704 gtk_widget_destroy (confirmation_dialog);
1705 if (!dialog_response) {
1707 g_list_free (att_list);
1710 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1712 for (node = att_list; node != NULL; node = g_list_next (node)) {
1713 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1714 const gchar *att_id;
1715 priv->attachments = g_list_remove (priv->attachments, mime_part);
1717 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1719 if (priv->attachments == NULL)
1720 gtk_widget_hide (priv->attachments_caption);
1721 att_id = tny_mime_part_get_content_id (mime_part);
1723 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1725 g_object_unref (mime_part);
1726 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1731 g_list_free (att_list);
1735 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1738 ModestMsgEditWindowPrivate *priv;
1739 GdkColor *new_color;
1740 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1742 #ifdef MODEST_HILDON_VERSION_0
1743 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1746 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1748 #endif /*MODEST_HILDON_VERSION_0*/
1750 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1752 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1757 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1760 ModestMsgEditWindowPrivate *priv;
1761 gint new_size_index;
1762 ModestMsgEditWindow *window;
1765 window = MODEST_MSG_EDIT_WINDOW (userdata);
1766 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1767 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1769 if (gtk_check_menu_item_get_active (menu_item)) {
1771 WPTextBufferFormat format;
1773 memset (&format, 0, sizeof (format));
1774 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1776 label = gtk_bin_get_child (GTK_BIN (menu_item));
1778 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1779 format.cs.font_size = TRUE;
1780 format.cs.text_position = TRUE;
1781 format.cs.font = TRUE;
1782 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1783 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1785 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1786 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1787 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1789 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1790 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1791 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1797 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1800 ModestMsgEditWindowPrivate *priv;
1801 gint new_font_index;
1802 ModestMsgEditWindow *window;
1805 window = MODEST_MSG_EDIT_WINDOW (userdata);
1806 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1807 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1809 if (gtk_check_menu_item_get_active (menu_item)) {
1812 label = gtk_bin_get_child (GTK_BIN (menu_item));
1814 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1816 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1817 (gpointer) new_font_index))
1818 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1820 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1821 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1822 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1828 modest_msg_edit_window_set_zoom (ModestWindow *window,
1831 ModestMsgEditWindowPrivate *priv;
1832 ModestWindowPrivate *parent_priv;
1833 GtkRadioAction *zoom_radio_action;
1835 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1837 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1838 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1839 priv->zoom_level = zoom;
1840 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1842 /* Zoom level menu options should be updated with the current zoom level */
1843 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1844 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1845 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1846 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1850 modest_msg_edit_window_get_zoom (ModestWindow *window)
1852 ModestMsgEditWindowPrivate *priv;
1854 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1856 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1857 return priv->zoom_level;
1861 zoom_allowed (ModestMsgEditWindow *window)
1865 focus = gtk_window_get_focus (GTK_WINDOW (window));
1866 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1870 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1872 ModestWindowPrivate *parent_priv;
1873 GtkRadioAction *zoom_radio_action;
1874 GSList *group, *node;
1876 /* First we check if the text view is focused. If not, zooming is not allowed */
1877 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1878 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1882 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1883 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1884 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1886 group = gtk_radio_action_get_group (zoom_radio_action);
1888 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1889 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1893 for (node = group; node != NULL; node = g_slist_next (node)) {
1894 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1895 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1903 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1905 ModestWindowPrivate *parent_priv;
1906 GtkRadioAction *zoom_radio_action;
1907 GSList *group, *node;
1909 /* First we check if the text view is focused. If not, zooming is not allowed */
1910 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1911 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1915 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1916 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1917 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1919 group = gtk_radio_action_get_group (zoom_radio_action);
1921 for (node = group; node != NULL; node = g_slist_next (node)) {
1922 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1923 if (node->next != NULL) {
1924 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1927 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1935 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1937 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1938 ModestWindowPrivate *parent_priv;
1939 ModestWindowMgr *mgr;
1940 gboolean is_fullscreen;
1941 GtkAction *fs_toggle_action;
1944 mgr = modest_runtime_get_window_mgr ();
1945 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1947 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1949 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1950 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1951 if (is_fullscreen != active)
1952 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1960 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1962 ModestWindowPrivate *parent_priv;
1963 GtkAction *fs_toggle_action;
1966 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1968 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1969 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1970 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1974 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1977 ModestMsgEditWindowPrivate *priv = NULL;
1978 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1980 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1981 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1983 gtk_widget_show (priv->cc_caption);
1985 gtk_widget_hide (priv->cc_caption);
1986 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1990 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1993 ModestMsgEditWindowPrivate *priv = NULL;
1994 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1996 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1997 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1999 gtk_widget_show (priv->bcc_caption);
2001 gtk_widget_hide (priv->bcc_caption);
2002 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2006 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2007 ModestRecptEditor *editor)
2009 ModestMsgEditWindowPrivate *priv;
2011 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2012 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2013 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2015 if (editor == NULL) {
2016 GtkWidget *view_focus;
2017 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2019 /* This code should be kept in sync with ModestRecptEditor. The
2020 textview inside the recpt editor is the one that really gets the
2021 focus. As it's inside a scrolled window, and this one inside the
2022 hbox recpt editor inherits from, we'll need to go up in the
2023 hierarchy to know if the text view is part of the recpt editor
2024 or if it's a different text entry */
2026 if (gtk_widget_get_parent (view_focus)) {
2027 GtkWidget *first_parent;
2029 first_parent = gtk_widget_get_parent (view_focus);
2030 if (gtk_widget_get_parent (first_parent) &&
2031 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2032 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2037 editor = MODEST_RECPT_EDITOR (priv->to_field);
2041 modest_address_book_select_addresses (editor);
2046 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2048 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2050 modest_msg_edit_window_open_addressbook (window, NULL);
2054 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2055 gboolean show_toolbar)
2057 ModestWindowPrivate *parent_priv;
2059 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2060 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2062 /* FIXME: we can not just use the code of
2063 modest_msg_edit_window_setup_toolbar because it has a
2064 mixture of both initialization and creation code. */
2067 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2069 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2073 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2074 TnyHeaderFlags priority_flags)
2076 ModestMsgEditWindowPrivate *priv;
2077 ModestWindowPrivate *parent_priv;
2079 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2081 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2082 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2083 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2085 if (priv->priority_flags != priority_flags) {
2086 GtkAction *priority_action = NULL;
2088 priv->priority_flags = priority_flags;
2090 switch (priority_flags) {
2091 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2092 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2093 gtk_widget_show (priv->priority_icon);
2094 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2095 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2097 case TNY_HEADER_FLAG_LOW_PRIORITY:
2098 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2099 gtk_widget_show (priv->priority_icon);
2100 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2101 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2104 gtk_widget_hide (priv->priority_icon);
2105 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2106 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2109 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2110 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2115 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2118 ModestMsgEditWindowPrivate *priv;
2119 gint current_format;
2121 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2123 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2125 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2126 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2128 if (current_format != file_format) {
2129 switch (file_format) {
2130 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2131 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2133 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2137 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2138 response = gtk_dialog_run (GTK_DIALOG (dialog));
2139 gtk_widget_destroy (dialog);
2140 if (response == GTK_RESPONSE_OK)
2141 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2145 update_dimmed (window);
2150 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2153 ModestMsgEditWindowPrivate *priv;
2154 WPTextBufferFormat oldfmt, fmt;
2155 gint old_position = 0;
2159 GdkColor *color = NULL;
2160 gboolean bold, bold_set, italic, italic_set;
2161 gboolean underline, underline_set;
2162 gboolean strikethrough, strikethrough_set;
2163 gboolean position_set;
2164 gboolean font_size_set, font_set, color_set;
2167 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2168 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2170 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2172 /* First we get the currently selected font information */
2173 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2174 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2176 switch (oldfmt.text_position) {
2177 case TEXT_POSITION_NORMAL:
2180 case TEXT_POSITION_SUPERSCRIPT:
2188 g_object_set (G_OBJECT (dialog),
2189 "bold", oldfmt.bold != FALSE,
2190 "bold-set", !oldfmt.cs.bold,
2191 "underline", oldfmt.underline != FALSE,
2192 "underline-set", !oldfmt.cs.underline,
2193 "italic", oldfmt.italic != FALSE,
2194 "italic-set", !oldfmt.cs.italic,
2195 "strikethrough", oldfmt.strikethrough != FALSE,
2196 "strikethrough-set", !oldfmt.cs.strikethrough,
2197 "color", &oldfmt.color,
2198 "color-set", !oldfmt.cs.color,
2199 "size", wp_font_size[oldfmt.font_size],
2200 "size-set", !oldfmt.cs.font_size,
2201 "position", old_position,
2202 "position-set", !oldfmt.cs.text_position,
2203 "family", wp_get_font_name (oldfmt.font),
2204 "family-set", !oldfmt.cs.font,
2207 gtk_widget_show_all (dialog);
2208 response = gtk_dialog_run (GTK_DIALOG (dialog));
2209 if (response == GTK_RESPONSE_OK) {
2211 g_object_get( dialog,
2213 "bold-set", &bold_set,
2214 "underline", &underline,
2215 "underline-set", &underline_set,
2217 "italic-set", &italic_set,
2218 "strikethrough", &strikethrough,
2219 "strikethrough-set", &strikethrough_set,
2221 "color-set", &color_set,
2223 "size-set", &font_size_set,
2224 "family", &font_name,
2225 "family-set", &font_set,
2226 "position", &position,
2227 "position-set", &position_set,
2232 if (response == GTK_RESPONSE_OK) {
2233 memset(&fmt, 0, sizeof(fmt));
2239 fmt.italic = italic;
2240 fmt.cs.italic = TRUE;
2242 if (underline_set) {
2243 fmt.underline = underline;
2244 fmt.cs.underline = TRUE;
2246 if (strikethrough_set) {
2247 fmt.strikethrough = strikethrough;
2248 fmt.cs.strikethrough = TRUE;
2253 ? TEXT_POSITION_NORMAL
2254 : ( ( position == 1 )
2255 ? TEXT_POSITION_SUPERSCRIPT
2256 : TEXT_POSITION_SUBSCRIPT );
2257 fmt.cs.text_position = TRUE;
2261 fmt.cs.color = TRUE;
2264 fmt.font = wp_get_font_index(font_name,
2269 if (font_size_set) {
2270 fmt.font_size = wp_get_font_size_index(
2271 font_size, DEFAULT_FONT_SIZE);
2272 fmt.cs.font_size = TRUE;
2274 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2276 gtk_widget_destroy (dialog);
2278 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2282 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2284 ModestMsgEditWindowPrivate *priv;
2286 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2287 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2289 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2291 update_dimmed (window);
2296 update_dimmed (ModestMsgEditWindow *window)
2298 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2299 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2303 gboolean editor_focused;
2305 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2306 editor_focused = gtk_widget_is_focus (priv->msg_body);
2308 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2309 gtk_action_set_sensitive (action, rich_text && editor_focused);
2310 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2311 gtk_action_set_sensitive (action, rich_text && editor_focused);
2312 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2313 gtk_action_set_sensitive (action, rich_text && editor_focused);
2314 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2315 gtk_action_set_sensitive (action, rich_text && editor_focused);
2316 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2317 gtk_action_set_sensitive (action, rich_text && editor_focused);
2318 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2319 gtk_action_set_sensitive (action, rich_text && editor_focused);
2320 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2321 gtk_action_set_sensitive (action, rich_text && editor_focused);
2322 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2323 gtk_action_set_sensitive (action, rich_text && editor_focused);
2324 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2325 gtk_action_set_sensitive (action, rich_text && editor_focused);
2326 widget = priv->font_color_button;
2327 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2328 widget = priv->font_size_toolitem;
2329 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2330 widget = priv->font_face_toolitem;
2331 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2335 setup_insensitive_handlers (ModestMsgEditWindow *window)
2337 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2338 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2341 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2342 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2343 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2344 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2346 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2347 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2348 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2349 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2350 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
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/AlignmentMenu/AlignmentLeftMenu");
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/AlignmentCenterMenu");
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/AlignmentRightMenu");
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/AttachmentsMenu/InsertImageMenu");
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, "/ToolBar/ActionsBold");
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, "/ToolBar/ActionsItalics");
2363 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2364 widget = priv->font_color_button;
2365 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2366 widget = priv->font_size_toolitem;
2367 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2368 widget = priv->font_face_toolitem;
2369 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2371 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2372 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (remove_attachment_insensitive_press), window);
2373 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2374 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (zoom_insensitive_press), window);
2378 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2380 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2383 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2384 gtk_action_set_sensitive (action, can_undo);
2388 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2391 GtkTextIter match_start, match_end;
2393 if (image_id == NULL)
2396 gtk_text_buffer_get_start_iter (buffer, &iter);
2398 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2399 GSList *tags = gtk_text_iter_get_tags (&match_start);
2401 for (node = tags; node != NULL; node = g_slist_next (node)) {
2402 GtkTextTag *tag = (GtkTextTag *) node->data;
2403 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2404 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2405 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2407 offset = gtk_text_iter_get_offset (&match_start);
2408 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2409 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2413 gtk_text_iter_forward_char (&iter);
2418 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2420 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2421 GtkTextIter real_start, real_end;
2422 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2424 if (gtk_text_iter_compare (start, end) > 0) {
2428 real_start = *start;
2432 GSList *tags = gtk_text_iter_get_tags (&real_start);
2434 for (node = tags; node != NULL; node = g_slist_next (node)) {
2435 GtkTextTag *tag = (GtkTextTag *) node->data;
2436 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2437 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2439 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2441 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2444 } while (gtk_text_iter_forward_char (&real_start)&&
2445 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2449 msg_body_focus (GtkWidget *focus,
2450 GdkEventFocus *event,
2454 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2459 recpt_field_changed (GtkTextBuffer *buffer,
2460 ModestMsgEditWindow *editor)
2462 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2463 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2464 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2465 gboolean dim = FALSE;
2468 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2469 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2470 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2472 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2473 gtk_text_buffer_get_char_count (cc_buffer) +
2474 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2476 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2477 gtk_action_set_sensitive (action, !dim);
2478 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2479 gtk_action_set_sensitive (action, !dim);
2483 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2485 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2489 zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2491 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2495 remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2497 ModestWindowPrivate *parent_priv;
2498 ModestMsgEditWindowPrivate *priv;
2499 GList *selected_attachments = NULL;
2500 gint n_att_selected = 0;
2502 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2503 parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2505 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2506 n_att_selected = g_list_length (selected_attachments);
2507 g_list_free (selected_attachments);
2509 if (n_att_selected > 1)
2510 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
2511 else if (n_att_selected == 0)
2512 hildon_banner_show_information (NULL, NULL, _("TODO: select one attachment"));
2517 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2519 gboolean rich_text, editor_focused;
2521 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2522 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2523 editor_focused = gtk_widget_is_focus (priv->msg_body);
2526 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2527 else if (!editor_focused)
2528 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2532 reset_modified (ModestMsgEditWindow *editor)
2534 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2535 GtkTextBuffer *buffer;
2537 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2538 gtk_text_buffer_set_modified (buffer, FALSE);
2539 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2540 gtk_text_buffer_set_modified (buffer, FALSE);
2541 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2542 gtk_text_buffer_set_modified (buffer, FALSE);
2543 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2547 is_modified (ModestMsgEditWindow *editor)
2549 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2550 GtkTextBuffer *buffer;
2552 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2553 if (gtk_text_buffer_get_modified (buffer))
2555 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2556 if (gtk_text_buffer_get_modified (buffer))
2558 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2559 if (gtk_text_buffer_get_modified (buffer))
2561 if (gtk_text_buffer_get_modified (priv->text_buffer))
2568 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2570 ModestMsgEditWindowPrivate *priv = NULL;
2572 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2573 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2575 /* check if there's no recipient added */
2576 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2577 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2578 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2579 /* no recipient contents, then select contacts */
2580 modest_msg_edit_window_open_addressbook (window, NULL);
2584 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2586 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2588 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2591 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2598 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2599 ModestMsgEditWindow *window)
2601 modest_msg_edit_window_attach_file (window);
2605 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2607 ModestMsgEditWindow *window)
2609 ModestWindowPrivate *parent_priv;
2610 ModestMsgEditWindowPrivate *priv;
2614 GList *selected_attachments = NULL;
2615 gint n_att_selected = 0;
2617 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2618 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2619 selection = gtk_clipboard_wait_for_text (clipboard);
2620 focused = gtk_window_get_focus (GTK_WINDOW (window));
2622 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2623 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2624 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2625 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2627 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2628 n_att_selected = g_list_length (selected_attachments);
2629 g_list_free (selected_attachments);
2631 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2632 gtk_action_set_sensitive (action, n_att_selected == 1);
2635 update_paste_dimming (window);
2639 update_window_title (ModestMsgEditWindow *window)
2641 ModestMsgEditWindowPrivate *priv = NULL;
2642 const gchar *subject;
2644 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2645 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2646 if (subject == NULL || subject[0] == '\0')
2647 subject = _("mail_va_new_email");
2649 gtk_window_set_title (GTK_WINDOW (window), subject);
2654 subject_field_changed (GtkEditable *editable,
2655 ModestMsgEditWindow *window)
2657 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2658 update_window_title (window);
2659 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2663 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2666 ModestMsgEditWindowPrivate *priv = NULL;
2668 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2669 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2671 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2673 gtk_widget_show_all (priv->find_toolbar);
2674 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2676 gtk_widget_hide_all (priv->find_toolbar);
2677 gtk_widget_grab_focus (priv->msg_body);
2683 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2684 ModestMsgEditWindow *window)
2686 gchar *current_search = NULL;
2687 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2689 GtkTextIter selection_start, selection_end;
2690 GtkTextIter match_start, match_end;
2692 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2693 if ((current_search == NULL) && (strcmp (current_search, "") == 0)) {
2694 g_free (current_search);
2698 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2699 result = gtk_text_iter_forward_search (&selection_end, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, NULL);
2701 GtkTextIter buffer_start;
2702 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2703 result = gtk_text_iter_forward_search (&buffer_start, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, &selection_start);
2706 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2707 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2709 /* TODO: warning about non succesful search */
2711 g_free (current_search);
2715 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2716 ModestMsgEditWindow *window)
2718 GtkToggleAction *toggle;
2719 ModestWindowPrivate *parent_priv;
2720 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2722 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2723 gtk_toggle_action_set_active (toggle, FALSE);
2728 update_paste_dimming (ModestMsgEditWindow *window)
2730 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2731 GtkAction *action = NULL;
2732 GtkClipboard *clipboard = NULL;
2734 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2736 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2737 gtk_action_set_sensitive (action, gtk_clipboard_wait_is_text_available (clipboard));
2742 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2744 ModestMsgEditWindow *window)
2746 update_paste_dimming (window);
2750 update_select_all_dimming (ModestMsgEditWindow *window)
2753 gboolean dimmed = FALSE;
2755 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2757 focused = gtk_window_get_focus (GTK_WINDOW (window));
2758 if (GTK_IS_ENTRY (focused)) {
2759 const gchar *current_text;
2760 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2761 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2762 } else if (GTK_IS_TEXT_VIEW (focused)) {
2763 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2764 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2765 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2768 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2769 gtk_action_set_sensitive (action, !dimmed);
2773 update_zoom_dimming (ModestMsgEditWindow *window)
2776 gboolean dimmed = FALSE;
2778 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2780 focused = gtk_window_get_focus (GTK_WINDOW (window));
2781 dimmed = ! WP_IS_TEXT_VIEW (focused);
2782 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2783 gtk_action_set_sensitive (action, !dimmed);
2787 edit_menu_activated (GtkAction *action,
2790 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2792 update_select_all_dimming (window);
2795 view_menu_activated (GtkAction *action,
2798 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2800 update_zoom_dimming (window);