1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37 #include <tny-vfs-stream.h>
41 #include <modest-account-mgr.h>
42 #include <modest-account-mgr-helpers.h>
44 #include <widgets/modest-msg-edit-window.h>
45 #include <widgets/modest-combo-box.h>
46 #include <widgets/modest-recpt-editor.h>
47 #include <widgets/modest-attachments-view.h>
49 #include <modest-runtime.h>
51 #include "modest-platform.h"
52 #include "modest-icon-names.h"
53 #include "modest-widget-memory.h"
54 #include "modest-window-priv.h"
55 #include "modest-mail-operation.h"
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-address-book.h"
59 #include "modest-text-utils.h"
60 #include <tny-simple-list.h>
61 #include <wptextview.h>
62 #include <wptextbuffer.h>
63 #include "modest-scroll-area.h"
65 #include "modest-hildon-includes.h"
66 #ifdef MODEST_HAVE_HILDON0_WIDGETS
67 #include <hildon-widgets/hildon-color-chooser.h>
69 #include "widgets/modest-msg-edit-window-ui.h"
70 #ifdef MODEST_HAVE_HILDON0_WIDGETS
71 #include <libgnomevfs/gnome-vfs-mime-utils.h>
73 #include <libgnomevfs/gnome-vfs-mime.h>
75 #include "modest-maemo-utils.h"
78 #define DEFAULT_FONT_SIZE 3
79 #define DEFAULT_FONT 2
80 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
81 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
82 #define DEFAULT_MAIN_VBOX_SPACING 6
83 #define SUBJECT_MAX_LENGTH 1000
84 #define IMAGE_MAX_WIDTH 640
86 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
87 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
88 static void modest_msg_edit_window_finalize (GObject *obj);
90 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
91 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
92 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
93 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
94 static void remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
95 static void zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
96 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
97 static void reset_modified (ModestMsgEditWindow *editor);
98 static gboolean is_modified (ModestMsgEditWindow *editor);
100 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
101 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
102 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
103 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
104 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
105 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
107 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
109 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
111 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
112 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
113 GdkEventWindowState *event,
115 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
116 ModestRecptEditor *editor);
117 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
118 ModestMsgEditWindow *window);
120 /* ModestWindow methods implementation */
121 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
122 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
123 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
124 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
125 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
126 gboolean show_toolbar);
127 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
129 ModestMsgEditWindow *window);
130 static void modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
132 ModestMsgEditWindow *window);
133 static void update_window_title (ModestMsgEditWindow *window);
134 static void update_dimmed (ModestMsgEditWindow *window);
135 static void update_paste_dimming (ModestMsgEditWindow *window);
136 static void update_select_all_dimming (ModestMsgEditWindow *window);
137 static void update_zoom_dimming (ModestMsgEditWindow *window);
140 static void modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
141 ModestMsgEditWindow *window);
142 static void modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
143 ModestMsgEditWindow *window);
144 static void edit_menu_activated (GtkAction *action,
146 static void view_menu_activated (GtkAction *action,
149 /* list my signals */
156 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
157 struct _ModestMsgEditWindowPrivate {
159 GtkWidget *header_box;
161 ModestPairList *from_field_protos;
162 GtkWidget *from_field;
166 GtkWidget *bcc_field;
167 GtkWidget *subject_field;
168 GtkWidget *attachments_view;
169 GtkWidget *priority_icon;
170 GtkWidget *add_attachment_button;
172 GtkWidget *cc_caption;
173 GtkWidget *bcc_caption;
174 GtkWidget *attachments_caption;
176 GtkTextBuffer *text_buffer;
178 GtkWidget *font_size_toolitem;
179 GtkWidget *font_face_toolitem;
180 GtkWidget *font_color_button;
181 GSList *font_items_group;
182 GtkWidget *font_tool_button_label;
183 GSList *size_items_group;
184 GtkWidget *size_tool_button_label;
186 GtkWidget *find_toolbar;
189 GtkWidget *scroll_area;
194 TnyHeaderFlags priority_flags;
198 gulong clipboard_change_handler_id;
199 gulong system_clipboard_change_handler_id;
204 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
205 MODEST_TYPE_MSG_EDIT_WINDOW, \
206 ModestMsgEditWindowPrivate))
208 static GtkWindowClass *parent_class = NULL;
210 /* uncomment the following if you have defined any signals */
211 /* static guint signals[LAST_SIGNAL] = {0}; */
214 modest_msg_edit_window_get_type (void)
216 static GType my_type = 0;
218 static const GTypeInfo my_info = {
219 sizeof(ModestMsgEditWindowClass),
220 NULL, /* base init */
221 NULL, /* base finalize */
222 (GClassInitFunc) modest_msg_edit_window_class_init,
223 NULL, /* class finalize */
224 NULL, /* class data */
225 sizeof(ModestMsgEditWindow),
227 (GInstanceInitFunc) modest_msg_edit_window_init,
230 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
231 "ModestMsgEditWindow",
234 wp_text_buffer_library_init ();
240 save_state (ModestWindow *self)
242 modest_widget_memory_save (modest_runtime_get_conf(),
243 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
248 restore_settings (ModestMsgEditWindow *self)
250 modest_widget_memory_restore (modest_runtime_get_conf(),
251 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
256 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
258 GObjectClass *gobject_class;
259 ModestWindowClass *modest_window_class;
260 gobject_class = (GObjectClass*) klass;
261 modest_window_class = (ModestWindowClass*) klass;
263 parent_class = g_type_class_peek_parent (klass);
264 gobject_class->finalize = modest_msg_edit_window_finalize;
266 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
267 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
268 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
269 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
270 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
272 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
274 modest_window_class->save_state_func = save_state;
278 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
280 ModestMsgEditWindowPrivate *priv;
281 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
283 priv->msg_body = NULL;
284 priv->from_field = NULL;
285 priv->to_field = NULL;
286 priv->cc_field = NULL;
287 priv->bcc_field = NULL;
288 priv->subject_field = NULL;
289 priv->attachments = NULL;
291 priv->zoom_level = 1.0;
293 priv->cc_caption = NULL;
294 priv->bcc_caption = NULL;
296 priv->priority_flags = 0;
298 priv->find_toolbar = NULL;
300 priv->draft_msg = NULL;
301 priv->clipboard_change_handler_id = 0;
302 priv->system_clipboard_change_handler_id = 0;
306 /* FIXME: this is a dup from the one in gtk/ */
309 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
311 static ModestPairList*
312 get_transports (void)
314 GSList *transports = NULL;
316 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
317 GSList *accounts = modest_account_mgr_account_names (account_mgr,
318 TRUE /* only enabled accounts. */);
320 GSList *cursor = accounts;
322 gchar *account_name = cursor->data;
323 gchar *from_string = NULL;
325 from_string = modest_account_mgr_get_from_string (account_mgr,
329 if (from_string && account_name) {
330 gchar *name = account_name;
331 ModestPair *pair = modest_pair_new ((gpointer) name,
332 (gpointer) from_string , TRUE);
333 transports = g_slist_prepend (transports, pair);
336 cursor = cursor->next;
338 g_slist_free (accounts); /* only free the accounts, not the elements,
339 * because they are used in the pairlist */
345 init_window (ModestMsgEditWindow *obj)
347 GtkWidget *from_caption, *to_caption, *subject_caption;
348 GtkWidget *main_vbox;
349 ModestMsgEditWindowPrivate *priv;
351 GtkSizeGroup *size_group;
353 GtkWidget *subject_box;
354 GtkWidget *attachment_icon;
355 GtkWidget *window_box;
357 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
359 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
361 /* Note: This ModestPairList* must exist for as long as the combo
362 * that uses it, because the ModestComboBox uses the ID opaquely,
363 * so it can't know how to manage its memory. */
364 priv->from_field_protos = get_transports ();
366 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
368 priv->to_field = modest_recpt_editor_new ();
369 priv->cc_field = modest_recpt_editor_new ();
370 priv->bcc_field = modest_recpt_editor_new ();
371 subject_box = gtk_hbox_new (FALSE, 0);
372 priv->priority_icon = gtk_image_new ();
373 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
374 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
375 hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->subject_field),
376 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
377 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
378 priv->add_attachment_button = gtk_button_new ();
379 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
380 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
381 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
382 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
383 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
384 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
385 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
386 priv->attachments_view = modest_attachments_view_new (NULL);
388 priv->header_box = gtk_vbox_new (FALSE, 0);
390 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
391 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
392 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
393 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
394 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
395 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
396 g_object_unref (size_group);
398 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
399 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
400 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
401 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
402 gtk_size_group_add_widget (size_group, priv->subject_field);
403 gtk_size_group_add_widget (size_group, priv->attachments_view);
404 g_object_unref (size_group);
406 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
407 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
408 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
409 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
410 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
411 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
412 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
415 priv->msg_body = wp_text_view_new ();
416 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
417 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
418 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
419 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
420 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
421 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
423 priv->find_toolbar = hildon_find_toolbar_new (NULL);
424 gtk_widget_set_no_show_all (priv->find_toolbar, TRUE);
426 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
427 G_CALLBACK (text_buffer_refresh_attributes), obj);
428 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
429 G_CALLBACK (text_buffer_delete_range), obj);
430 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
431 G_CALLBACK (text_buffer_can_undo), obj);
432 g_signal_connect (G_OBJECT (obj), "window-state-event",
433 G_CALLBACK (modest_msg_edit_window_window_state_event),
435 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
436 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
437 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
438 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
439 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
440 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
442 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
443 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
445 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
446 G_CALLBACK (msg_body_focus), obj);
447 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
448 G_CALLBACK (msg_body_focus), obj);
449 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
450 "changed", G_CALLBACK (recpt_field_changed), obj);
451 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
452 "changed", G_CALLBACK (recpt_field_changed), obj);
453 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
454 "changed", G_CALLBACK (recpt_field_changed), obj);
455 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
456 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
458 g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_edit_window_find_toolbar_close), obj);
459 g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_edit_window_find_toolbar_search), obj);
461 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
462 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
463 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
465 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
467 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
468 frame = gtk_frame_new (NULL);
469 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
471 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
472 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
473 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
475 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
476 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
477 gtk_widget_hide (priv->cc_caption);
479 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
480 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
481 gtk_widget_hide (priv->bcc_caption);
484 window_box = gtk_vbox_new (FALSE, 0);
485 gtk_box_pack_start (GTK_BOX (window_box), priv->scroll, TRUE, TRUE, 0);
486 gtk_box_pack_end (GTK_BOX (window_box), priv->find_toolbar, FALSE, FALSE, 0);
487 gtk_container_add (GTK_CONTAINER(obj), window_box);
488 priv->scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
489 gtk_container_add (GTK_CONTAINER (frame), priv->scroll_area);
492 TODO: scroll_area was never instantiated.
493 Stop building without warnings-as-errors. murrayc.
494 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
495 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
498 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
499 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
500 priv->system_clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)), "owner-change",
501 G_CALLBACK (modest_msg_edit_window_system_clipboard_owner_change), obj);
507 modest_msg_edit_window_finalize (GObject *obj)
509 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
511 if (priv->clipboard_change_handler_id > 0) {
512 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
513 priv->clipboard_change_handler_id = 0;
516 if (priv->system_clipboard_change_handler_id > 0) {
517 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD),
518 priv->system_clipboard_change_handler_id);
519 priv->system_clipboard_change_handler_id = 0;
522 /* This had to stay alive for as long as the combobox that used it: */
523 modest_pair_list_free (priv->from_field_protos);
525 G_OBJECT_CLASS(parent_class)->finalize (obj);
529 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
531 GtkWidget *close_dialog;
532 ModestMsgEditWindowPrivate *priv;
535 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
536 modest_window_save_state (MODEST_WINDOW (self));
537 if (is_modified (self)) {
538 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
539 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
540 gtk_widget_destroy (close_dialog);
542 if (response != GTK_RESPONSE_CANCEL) {
543 modest_ui_actions_on_save_to_drafts (NULL, self);
546 /* /\* remove old message from drafts *\/ */
547 /* if (priv->draft_msg) { */
548 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
549 /* TnyAccount *account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(), */
551 /* TNY_ACCOUNT_TYPE_STORE); */
552 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
553 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
554 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
555 /* tny_folder_remove_msg (folder, header, NULL); */
556 /* g_object_unref (folder); */
557 /* g_object_unref (header); */
558 /* g_object_unref (priv->draft_msg); */
559 /* priv->draft_msg = NULL; */
561 gtk_widget_destroy (GTK_WIDGET (self));
567 menubar_to_menu (GtkUIManager *ui_manager)
569 GtkWidget *main_menu;
573 /* Create new main menu */
574 main_menu = gtk_menu_new();
576 /* Get the menubar from the UI manager */
577 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
579 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
583 menu = GTK_WIDGET (iter->data);
584 gtk_widget_reparent(menu, main_menu);
586 iter = g_list_next (iter);
593 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
596 const gchar *to, *cc, *bcc, *subject;
598 ModestMsgEditWindowPrivate *priv;
600 TnyHeaderFlags priority_flags;
602 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
603 g_return_if_fail (TNY_IS_MSG (msg));
605 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
607 header = tny_msg_get_header (msg);
608 to = tny_header_get_to (header);
609 cc = tny_header_get_cc (header);
610 bcc = tny_header_get_bcc (header);
611 subject = tny_header_get_subject (header);
612 priority_flags = tny_header_get_flags (header) & TNY_HEADER_FLAG_PRIORITY;
615 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
617 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
619 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
621 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
622 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW(self),
625 update_window_title (self);
627 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
628 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
629 body = modest_tny_msg_get_body (msg, TRUE);
631 if ((body == NULL)||(body[0] == '\0')) {
633 body = modest_text_utils_convert_to_html ("");
635 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
636 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
639 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
642 /* Get the default format required from configuration */
643 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
644 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
647 /* Set the default focus depending on having already a To: field or not */
648 if ((!to)||(*to == '\0')) {
649 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
651 gtk_widget_grab_focus (priv->msg_body);
654 /* TODO: lower priority, select in the From: combo to the
655 value that comes from msg <- not sure, should it be
658 /* Add attachments to the view */
659 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
660 priv->attachments = modest_attachments_view_get_attachments (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
661 if (priv->attachments == NULL) {
662 gtk_widget_hide (priv->attachments_caption);
664 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
665 gtk_widget_show_all (priv->attachments_caption);
668 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
669 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
671 reset_modified (self);
673 update_dimmed (self);
674 text_buffer_can_undo (priv->text_buffer, FALSE, self);
676 priv->draft_msg = msg;
680 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
683 GList *item_children, *node;
684 GtkWidget *bin_child;
686 bin_child = gtk_bin_get_child (GTK_BIN(item));
688 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
690 for (node = item_children; node != NULL; node = g_list_next (node)) {
691 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
692 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
695 g_list_free (item_children);
699 menu_tool_button_dont_expand (GtkMenuToolButton *item)
702 GList *item_children, *node;
704 box = gtk_bin_get_child (GTK_BIN (item));
705 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
706 item_children = gtk_container_get_children (GTK_CONTAINER (box));
708 for (node = item_children; node != NULL; node = g_list_next (node)) {
709 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
710 if (GTK_IS_TOGGLE_BUTTON (node->data))
711 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
712 else if (GTK_IS_BUTTON (node->data))
713 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
715 g_list_free (item_children);
720 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
722 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
723 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
724 GtkWidget *placeholder;
725 GtkWidget *tool_item;
730 GtkWidget *sizes_menu;
731 GtkWidget *fonts_menu;
732 GSList *radio_group = NULL;
737 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
738 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
740 /* should we hide the toolbar? */
741 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
742 gtk_widget_hide (parent_priv->toolbar);
744 /* Font color placeholder */
745 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
746 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
749 tool_item = GTK_WIDGET (gtk_tool_item_new ());
750 priv->font_color_button = hildon_color_button_new ();
751 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
752 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
753 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
754 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
755 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
756 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
757 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
759 /* Font size and face placeholder */
760 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
761 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
763 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
764 priv->size_tool_button_label = gtk_label_new (NULL);
765 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
766 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
767 size_text,"</span>", NULL);
768 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
770 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
771 sizes_menu = gtk_menu_new ();
772 priv->size_items_group = NULL;
774 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
775 GtkWidget *size_menu_item;
777 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
778 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
779 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
780 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
781 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
782 gtk_widget_show (size_menu_item);
784 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
788 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
789 GtkWidget *item = (GtkWidget *) node->data;
790 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
794 priv->size_items_group = g_slist_reverse (priv->size_items_group);
795 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
796 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
797 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
798 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
799 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
800 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
801 priv->font_size_toolitem = tool_item;
804 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
805 priv->font_tool_button_label = gtk_label_new (NULL);
806 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
807 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
809 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
810 fonts_menu = gtk_menu_new ();
811 priv->font_items_group = NULL;
813 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
814 GtkWidget *font_menu_item;
815 GtkWidget *child_label;
817 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
818 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
819 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
820 wp_get_font_name (font_index), "</span>", NULL);
821 gtk_label_set_markup (GTK_LABEL (child_label), markup);
824 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
825 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
826 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
827 gtk_widget_show (font_menu_item);
829 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
832 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
833 GtkWidget *item = (GtkWidget *) node->data;
834 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
837 priv->font_items_group = g_slist_reverse (priv->font_items_group);
838 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
839 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
840 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
841 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
842 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
843 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
844 priv->font_face_toolitem = tool_item;
846 /* Set expand and homogeneous for remaining items */
847 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
848 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
849 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
850 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
851 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
852 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
853 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
854 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
855 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
863 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
866 ModestWindowPrivate *parent_priv;
867 ModestMsgEditWindowPrivate *priv;
868 GtkActionGroup *action_group;
869 GError *error = NULL;
870 GdkPixbuf *window_icon = NULL;
873 gboolean prefer_formatted;
875 ModestPair *account_pair = NULL;
877 g_return_val_if_fail (msg, NULL);
878 g_return_val_if_fail (account_name, NULL);
880 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
882 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
883 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
885 parent_priv->ui_manager = gtk_ui_manager_new();
886 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
887 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
889 /* Add common actions */
890 gtk_action_group_add_actions (action_group,
891 modest_msg_edit_action_entries,
892 G_N_ELEMENTS (modest_msg_edit_action_entries),
894 gtk_action_group_add_toggle_actions (action_group,
895 modest_msg_edit_toggle_action_entries,
896 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
898 gtk_action_group_add_radio_actions (action_group,
899 modest_msg_edit_alignment_radio_action_entries,
900 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
902 G_CALLBACK (modest_ui_actions_on_change_justify),
904 gtk_action_group_add_radio_actions (action_group,
905 modest_msg_edit_zoom_action_entries,
906 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
908 G_CALLBACK (modest_ui_actions_on_change_zoom),
910 gtk_action_group_add_radio_actions (action_group,
911 modest_msg_edit_priority_action_entries,
912 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
914 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
916 gtk_action_group_add_radio_actions (action_group,
917 modest_msg_edit_file_format_action_entries,
918 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
919 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
920 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
922 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
923 g_object_unref (action_group);
925 /* Load the UI definition */
926 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml",
929 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
930 g_clear_error (&error);
933 /* Add accelerators */
934 gtk_window_add_accel_group (GTK_WINDOW (obj),
935 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
938 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
939 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
942 init_window (MODEST_MSG_EDIT_WINDOW(obj));
944 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
946 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
948 g_signal_connect (G_OBJECT(obj), "delete-event",
949 G_CALLBACK(on_delete_event), obj);
951 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
953 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
955 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
957 account_pair = modest_pair_list_find_by_first_as_string (priv->from_field_protos, account_name);
958 if (account_pair != NULL)
959 modest_combo_box_set_active_id (MODEST_COMBO_BOX (priv->from_field), account_pair->first);
961 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
963 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
965 /* Set window icon */
966 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
967 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
969 /* Dim at start clipboard actions */
970 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
971 gtk_action_set_sensitive (action, FALSE);
972 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
973 gtk_action_set_sensitive (action, FALSE);
974 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
975 gtk_action_set_sensitive (action, FALSE);
977 /* Update select all */
978 update_select_all_dimming (MODEST_MSG_EDIT_WINDOW (obj));
979 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu");
980 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (edit_menu_activated), obj);
981 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu");
982 g_signal_connect (G_OBJECT (action), "activate", G_CALLBACK (view_menu_activated), obj);
984 /* set initial state of cc and bcc */
985 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
986 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
987 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
988 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
989 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
990 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
992 /* Setup the file format */
993 conf = modest_runtime_get_conf ();
994 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
996 g_clear_error (&error);
997 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
999 file_format = (prefer_formatted) ?
1000 MODEST_FILE_FORMAT_FORMATTED_TEXT :
1001 MODEST_FILE_FORMAT_PLAIN_TEXT;
1002 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
1004 update_paste_dimming (MODEST_MSG_EDIT_WINDOW (obj));
1006 return (ModestWindow*) obj;
1010 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
1012 GString **string_buffer = (GString **) user_data;
1014 *string_buffer = g_string_append (*string_buffer, buffer);
1020 * @result: A new string which should be freed with g_free().
1023 get_formatted_data (ModestMsgEditWindow *edit_window)
1025 ModestMsgEditWindowPrivate *priv;
1026 GString *string_buffer = g_string_new ("");
1028 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1030 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
1032 return g_string_free (string_buffer, FALSE);
1037 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
1040 const gchar *account_name;
1041 ModestMsgEditWindowPrivate *priv;
1043 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
1045 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
1047 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
1048 g_return_val_if_fail (account_name, NULL);
1051 /* don't free these (except from) */
1052 data = g_slice_new0 (MsgData);
1053 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1055 data->account_name = g_strdup (account_name);
1056 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
1057 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
1058 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
1059 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
1060 if (priv->draft_msg) {
1061 data->draft_msg = g_object_ref (priv->draft_msg);
1063 data->draft_msg = NULL;
1066 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
1068 gtk_text_buffer_get_bounds (buf, &b, &e);
1069 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
1071 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
1072 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
1074 data->html_body = NULL;
1076 data->attachments = priv->attachments; /* TODO: copy and free ? */
1077 data->priority_flags = priv->priority_flags;
1082 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1084 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1087 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1095 g_free (data->subject);
1096 g_free (data->plain_body);
1097 g_free (data->html_body);
1098 if (data->draft_msg != NULL) {
1099 g_object_unref (data->draft_msg);
1100 data->draft_msg = NULL;
1102 g_free (data->account_name);
1104 /* TODO: Free data->attachments? */
1106 g_slice_free (MsgData, data);
1110 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1113 ModestMsgEditWindowPrivate *priv = NULL;
1114 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1116 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1118 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1120 return MODEST_MSG_EDIT_FORMAT_HTML;
1122 return MODEST_MSG_EDIT_FORMAT_TEXT;
1126 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1127 ModestMsgEditFormat format)
1129 ModestMsgEditWindowPrivate *priv;
1131 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1132 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1135 case MODEST_MSG_EDIT_FORMAT_HTML:
1136 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1138 case MODEST_MSG_EDIT_FORMAT_TEXT:
1139 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1142 g_return_if_reached ();
1146 ModestMsgEditFormatState *
1147 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1149 ModestMsgEditFormatState *format_state = NULL;
1150 ModestMsgEditWindowPrivate *priv;
1151 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1153 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1154 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1156 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1158 format_state = g_new0 (ModestMsgEditFormatState, 1);
1159 format_state->bold = buffer_format->bold&0x1;
1160 format_state->italics = buffer_format->italic&0x1;
1161 format_state->bullet = buffer_format->bullet&0x1;
1162 format_state->color = buffer_format->color;
1163 format_state->font_size = buffer_format->font_size;
1164 format_state->font_family = wp_get_font_name (buffer_format->font);
1165 format_state->justification = buffer_format->justification;
1166 g_free (buffer_format);
1168 return format_state;
1173 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1174 const ModestMsgEditFormatState *format_state)
1176 ModestMsgEditWindowPrivate *priv;
1177 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1178 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1179 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1180 g_return_if_fail (format_state != NULL);
1182 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1183 gtk_widget_grab_focus (priv->msg_body);
1184 buffer_format->bold = (format_state->bold != FALSE);
1185 buffer_format->italic = (format_state->italics != FALSE);
1186 buffer_format->color = format_state->color;
1187 buffer_format->font_size = format_state->font_size;
1188 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1189 buffer_format->justification = format_state->justification;
1190 buffer_format->bullet = format_state->bullet;
1192 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1194 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1195 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1196 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1197 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1198 buffer_format->cs.font = (buffer_format->font != current_format->font);
1199 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1200 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1202 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1203 if (buffer_format->cs.bold) {
1204 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1206 if (buffer_format->cs.italic) {
1207 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1209 if (buffer_format->cs.color) {
1210 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1212 if (buffer_format->cs.font_size) {
1213 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1215 if (buffer_format->cs.justification) {
1216 switch (buffer_format->justification) {
1217 case GTK_JUSTIFY_LEFT:
1218 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1220 case GTK_JUSTIFY_CENTER:
1221 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1223 case GTK_JUSTIFY_RIGHT:
1224 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1231 if (buffer_format->cs.font) {
1232 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1234 if (buffer_format->cs.bullet) {
1235 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) ((int)buffer_format->bullet));
1237 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1238 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1240 g_free (current_format);
1245 toggle_action_set_active_block_notify (GtkToggleAction *action,
1248 GSList *proxies = NULL;
1250 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1251 proxies != NULL; proxies = g_slist_next (proxies)) {
1252 GtkWidget *widget = (GtkWidget *) proxies->data;
1253 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1256 gtk_toggle_action_set_active (action, value);
1258 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1259 proxies != NULL; proxies = g_slist_next (proxies)) {
1260 GtkWidget *widget = (GtkWidget *) proxies->data;
1261 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1266 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1268 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1270 ModestWindowPrivate *parent_priv;
1271 ModestMsgEditWindowPrivate *priv;
1272 GtkWidget *new_size_menuitem;
1273 GtkWidget *new_font_menuitem;
1275 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1276 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1278 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1279 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1280 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1281 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1283 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1284 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1285 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1288 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1290 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1291 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1293 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1294 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1296 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1297 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1299 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1300 G_CALLBACK (modest_msg_edit_window_color_button_change),
1302 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1303 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1304 G_CALLBACK (modest_msg_edit_window_color_button_change),
1307 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1308 buffer_format->font_size))->data);
1309 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1313 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1314 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1315 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1317 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1318 G_CALLBACK (modest_msg_edit_window_size_change),
1320 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1321 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1322 G_CALLBACK (modest_msg_edit_window_size_change),
1326 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1327 buffer_format->font))->data);
1328 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1332 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1333 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1334 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1336 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1337 G_CALLBACK (modest_msg_edit_window_font_change),
1339 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1340 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1341 G_CALLBACK (modest_msg_edit_window_font_change),
1345 g_free (buffer_format);
1351 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1354 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1355 ModestMsgEditWindowPrivate *priv;
1356 GtkWidget *dialog = NULL;
1358 const GdkColor *new_color = NULL;
1360 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1361 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1363 #ifdef MODEST_HILDON_VERSION_0
1364 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1365 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1367 dialog = hildon_color_chooser_new ();
1368 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1369 #endif /*MODEST_HILDON_VERSION_0*/
1370 g_free (buffer_format);
1372 response = gtk_dialog_run (GTK_DIALOG (dialog));
1374 case GTK_RESPONSE_OK: {
1375 #ifdef MODEST_HILDON_VERSION_0
1376 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1379 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1381 #endif /*MODEST_HILDON_VERSION_0*/
1388 gtk_widget_destroy (dialog);
1390 if (new_color != NULL)
1391 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1396 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1399 ModestMsgEditWindowPrivate *priv;
1400 GtkWidget *dialog = NULL;
1402 GdkColor *old_color = NULL;
1403 const GdkColor *new_color = NULL;
1405 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1406 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1408 #ifdef MODEST_HILDON_VERSION_0
1409 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1410 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1412 dialog = hildon_color_chooser_new ();
1413 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1414 #endif /*MODEST_HILDON_VERSION_9*/
1416 response = gtk_dialog_run (GTK_DIALOG (dialog));
1418 case GTK_RESPONSE_OK: {
1419 #ifdef MODEST_HILDON_VERSION_0
1420 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1423 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1425 #endif /*MODEST_HILDON_VERSION_0*/
1431 gtk_widget_destroy (dialog);
1433 if (new_color != NULL)
1434 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1440 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1443 ModestMsgEditWindowPrivate *priv;
1444 GtkWidget *dialog = NULL;
1446 GSList *uris = NULL;
1447 GSList *uri_node = NULL;
1449 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1451 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1452 gtk_window_set_title (GTK_WINDOW (dialog), _("mcen_ia_select_inline_image_title"));
1453 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1455 modest_maemo_utils_setup_images_filechooser (GTK_FILE_CHOOSER (dialog));
1457 response = gtk_dialog_run (GTK_DIALOG (dialog));
1459 case GTK_RESPONSE_OK:
1460 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1465 gtk_widget_destroy (dialog);
1467 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1469 GnomeVFSHandle *handle = NULL;
1470 GnomeVFSResult result;
1471 GtkTextIter position;
1472 GtkTextMark *insert_mark;
1474 uri = (const gchar *) uri_node->data;
1475 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1476 if (result == GNOME_VFS_OK) {
1477 GdkPixbufLoader *loader;
1479 GnomeVFSFileInfo info;
1480 gchar *filename, *basename;
1481 TnyMimePart *mime_part;
1484 const gchar *mime_type = NULL;
1486 filename = g_filename_from_uri (uri, NULL, NULL);
1487 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
1489 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1491 mime_part = tny_platform_factory_new_mime_part
1492 (modest_runtime_get_platform_factory ());
1493 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1495 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1497 content_id = g_strdup_printf ("%d", priv->last_cid);
1498 tny_mime_part_set_content_id (mime_part, content_id);
1499 g_free (content_id);
1502 basename = g_path_get_basename (filename);
1503 tny_mime_part_set_filename (mime_part, basename);
1506 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1507 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1509 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1510 gtk_widget_show_all (priv->attachments_caption);
1511 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1514 loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);
1515 while (!tny_stream_is_eos (TNY_STREAM (stream))) {
1516 char read_buffer[128];
1518 readed = tny_stream_read (TNY_STREAM (stream), read_buffer, 128);
1519 if (!gdk_pixbuf_loader_write (loader, read_buffer, readed, NULL))
1522 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
1523 g_object_ref (pixbuf);
1524 gdk_pixbuf_loader_close (loader, NULL);
1525 g_object_unref (loader);
1527 if (gdk_pixbuf_get_width (pixbuf) > IMAGE_MAX_WIDTH) {
1528 GdkPixbuf *new_pixbuf;
1530 new_height = (gdk_pixbuf_get_height (pixbuf) * IMAGE_MAX_WIDTH) /
1531 gdk_pixbuf_get_width (pixbuf);
1532 new_pixbuf = gdk_pixbuf_scale_simple (pixbuf, IMAGE_MAX_WIDTH, new_height, GDK_INTERP_BILINEAR);
1533 g_object_unref (pixbuf);
1534 pixbuf = new_pixbuf;
1537 if (pixbuf != NULL) {
1538 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1539 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1540 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (mime_part)), pixbuf);
1549 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1552 ModestMsgEditWindowPrivate *priv;
1553 GtkWidget *dialog = NULL;
1555 GSList *uris = NULL;
1558 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1560 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1561 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dialog), TRUE);
1563 response = gtk_dialog_run (GTK_DIALOG (dialog));
1565 case GTK_RESPONSE_OK:
1566 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (dialog));
1571 gtk_widget_destroy (dialog);
1573 for (uri_node = uris; uri_node != NULL; uri_node = g_slist_next (uri_node)) {
1575 GnomeVFSHandle *handle = NULL;
1576 GnomeVFSResult result;
1578 uri = (const gchar *) uri_node->data;
1579 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1580 if (result == GNOME_VFS_OK) {
1581 TnyMimePart *mime_part;
1583 const gchar *mime_type = NULL;
1587 GnomeVFSFileInfo info;
1589 filename = g_filename_from_uri (uri, NULL, NULL);
1591 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1592 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1593 mime_part = tny_platform_factory_new_mime_part
1594 (modest_runtime_get_platform_factory ());
1595 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1597 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1599 content_id = g_strdup_printf ("%d", priv->last_cid);
1600 tny_mime_part_set_content_id (mime_part, content_id);
1601 g_free (content_id);
1604 basename = g_path_get_basename (filename);
1605 tny_mime_part_set_filename (mime_part, basename);
1608 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1609 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1611 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1612 gtk_widget_show_all (priv->attachments_caption);
1613 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1618 g_slist_foreach (uris, (GFunc) g_free, NULL);
1619 g_slist_free (uris);
1623 modest_msg_edit_window_attach_file_noninteractive (
1624 ModestMsgEditWindow *window,
1625 const gchar *file_uri)
1628 ModestMsgEditWindowPrivate *priv;
1630 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1635 /* TODO: We should probably try to use only the URI,
1636 * instead of using a filename.
1638 gchar* filename = g_filename_from_uri (file_uri, NULL, NULL);
1640 g_warning("%s: g_filename_from_uri(%s) failed.\n", __FUNCTION__, file_uri);
1643 file_id = g_open (filename, O_RDONLY, 0);
1644 if (file_id != -1) {
1645 TnyMimePart *mime_part;
1647 const gchar *mime_type;
1650 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1651 mime_type = gnome_vfs_get_mime_type(filename);
1653 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1655 mime_part = tny_platform_factory_new_mime_part
1656 (modest_runtime_get_platform_factory ());
1657 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1659 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1661 content_id = g_strdup_printf ("%d", priv->last_cid);
1662 tny_mime_part_set_content_id (mime_part, content_id);
1663 g_free (content_id);
1666 basename = g_path_get_basename (filename);
1667 tny_mime_part_set_filename (mime_part, basename);
1670 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1671 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1673 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1674 gtk_widget_show_all (priv->attachments_caption);
1675 } else if (file_id == -1) {
1677 g_warning("file to be attached does not exist: %s", filename);
1685 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1688 ModestMsgEditWindowPrivate *priv;
1689 gboolean clean_list = FALSE;
1691 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1692 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1694 if (att_list == NULL) {
1695 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1699 if (att_list == NULL) {
1700 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1702 GtkWidget *confirmation_dialog = NULL;
1703 gboolean dialog_response;
1705 gchar *message = NULL;
1706 const gchar *filename = NULL;
1708 if (att_list->next == NULL) {
1709 filename = tny_mime_part_get_filename (TNY_MIME_PART (att_list->data));
1713 message = g_strdup_printf (ngettext("emev_nc_delete_attachment", "emev_nc_delete_attachments",
1714 att_list->next == NULL), filename);
1715 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1717 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1718 gtk_widget_destroy (confirmation_dialog);
1719 if (!dialog_response) {
1721 g_list_free (att_list);
1724 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1726 for (node = att_list; node != NULL; node = g_list_next (node)) {
1727 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1728 const gchar *att_id;
1729 priv->attachments = g_list_remove (priv->attachments, mime_part);
1731 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1733 if (priv->attachments == NULL)
1734 gtk_widget_hide (priv->attachments_caption);
1735 att_id = tny_mime_part_get_content_id (mime_part);
1737 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1739 g_object_unref (mime_part);
1740 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1745 g_list_free (att_list);
1749 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1752 ModestMsgEditWindowPrivate *priv;
1753 GdkColor *new_color;
1754 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1756 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1757 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1760 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1762 #endif /*#ifdef MODEST_HAVE_HILDON0_WIDGETS*/
1764 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1766 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1771 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1774 ModestMsgEditWindowPrivate *priv;
1775 gint new_size_index;
1776 ModestMsgEditWindow *window;
1779 window = MODEST_MSG_EDIT_WINDOW (userdata);
1780 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1781 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1783 if (gtk_check_menu_item_get_active (menu_item)) {
1785 WPTextBufferFormat format;
1787 memset (&format, 0, sizeof (format));
1788 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1790 label = gtk_bin_get_child (GTK_BIN (menu_item));
1792 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1793 format.cs.font_size = TRUE;
1794 format.cs.text_position = TRUE;
1795 format.cs.font = TRUE;
1796 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1797 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1799 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1800 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1801 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1803 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1804 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1805 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1811 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1814 ModestMsgEditWindowPrivate *priv;
1815 gint new_font_index;
1816 ModestMsgEditWindow *window;
1819 window = MODEST_MSG_EDIT_WINDOW (userdata);
1820 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1821 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1823 if (gtk_check_menu_item_get_active (menu_item)) {
1826 label = gtk_bin_get_child (GTK_BIN (menu_item));
1828 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1830 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1831 (gpointer) new_font_index))
1832 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1834 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1835 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1836 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1842 modest_msg_edit_window_set_zoom (ModestWindow *window,
1845 ModestMsgEditWindowPrivate *priv;
1846 ModestWindowPrivate *parent_priv;
1847 GtkRadioAction *zoom_radio_action;
1849 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1851 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1852 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1853 priv->zoom_level = zoom;
1854 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1856 /* Zoom level menu options should be updated with the current zoom level */
1857 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1858 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1859 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1860 #ifdef MODEST_HAVE_HILDON0_WIDGETS
1861 /* FIXME: Not availible before Gtk 2.10 */
1863 gtk_radio_action_set_current_value (zoom_radio_action, (gint) (zoom*100.0+0.1));
1868 modest_msg_edit_window_get_zoom (ModestWindow *window)
1870 ModestMsgEditWindowPrivate *priv;
1872 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1874 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1875 return priv->zoom_level;
1879 zoom_allowed (ModestMsgEditWindow *window)
1883 focus = gtk_window_get_focus (GTK_WINDOW (window));
1884 return (focus != NULL && WP_IS_TEXT_VIEW (focus));
1888 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1890 ModestWindowPrivate *parent_priv;
1891 GtkRadioAction *zoom_radio_action;
1892 GSList *group, *node;
1894 /* First we check if the text view is focused. If not, zooming is not allowed */
1895 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1896 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1900 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1901 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1902 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1904 group = gtk_radio_action_get_group (zoom_radio_action);
1906 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1907 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_max_zoom_level_reached"));
1911 for (node = group; node != NULL; node = g_slist_next (node)) {
1912 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1913 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1921 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1923 ModestWindowPrivate *parent_priv;
1924 GtkRadioAction *zoom_radio_action;
1925 GSList *group, *node;
1927 /* First we check if the text view is focused. If not, zooming is not allowed */
1928 if (!zoom_allowed (MODEST_MSG_EDIT_WINDOW (window))) {
1929 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
1933 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1934 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1935 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1937 group = gtk_radio_action_get_group (zoom_radio_action);
1939 for (node = group; node != NULL; node = g_slist_next (node)) {
1940 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1941 if (node->next != NULL) {
1942 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1945 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_min_zoom_level_reached"));
1953 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1955 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1956 ModestWindowPrivate *parent_priv;
1957 ModestWindowMgr *mgr;
1958 gboolean is_fullscreen;
1959 GtkAction *fs_toggle_action;
1962 mgr = modest_runtime_get_window_mgr ();
1963 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1965 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1967 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1968 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1969 if (is_fullscreen != active)
1970 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1978 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1980 ModestWindowPrivate *parent_priv;
1981 GtkAction *fs_toggle_action;
1984 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1986 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1987 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1988 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1992 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1995 ModestMsgEditWindowPrivate *priv = NULL;
1996 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1998 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1999 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
2001 gtk_widget_show (priv->cc_caption);
2003 gtk_widget_hide (priv->cc_caption);
2004 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
2008 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
2011 ModestMsgEditWindowPrivate *priv = NULL;
2012 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2014 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2015 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
2017 gtk_widget_show (priv->bcc_caption);
2019 gtk_widget_hide (priv->bcc_caption);
2020 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
2024 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
2025 ModestRecptEditor *editor)
2027 ModestMsgEditWindowPrivate *priv;
2029 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2030 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
2031 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2033 if (editor == NULL) {
2034 GtkWidget *view_focus;
2035 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
2037 /* This code should be kept in sync with ModestRecptEditor. The
2038 textview inside the recpt editor is the one that really gets the
2039 focus. As it's inside a scrolled window, and this one inside the
2040 hbox recpt editor inherits from, we'll need to go up in the
2041 hierarchy to know if the text view is part of the recpt editor
2042 or if it's a different text entry */
2044 if (gtk_widget_get_parent (view_focus)) {
2045 GtkWidget *first_parent;
2047 first_parent = gtk_widget_get_parent (view_focus);
2048 if (gtk_widget_get_parent (first_parent) &&
2049 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
2050 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
2055 editor = MODEST_RECPT_EDITOR (priv->to_field);
2059 modest_address_book_select_addresses (editor);
2064 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
2066 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2068 modest_msg_edit_window_open_addressbook (window, NULL);
2072 modest_msg_edit_window_show_toolbar (ModestWindow *self,
2073 gboolean show_toolbar)
2075 ModestWindowPrivate *parent_priv;
2077 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
2078 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2080 /* FIXME: we can not just use the code of
2081 modest_msg_edit_window_setup_toolbar because it has a
2082 mixture of both initialization and creation code. */
2085 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2087 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
2091 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
2092 TnyHeaderFlags priority_flags)
2094 ModestMsgEditWindowPrivate *priv;
2095 ModestWindowPrivate *parent_priv;
2097 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2099 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2100 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2101 priority_flags = priority_flags & (TNY_HEADER_FLAG_PRIORITY);
2103 if (priv->priority_flags != priority_flags) {
2104 GtkAction *priority_action = NULL;
2106 priv->priority_flags = priority_flags;
2108 switch (priority_flags) {
2109 case TNY_HEADER_FLAG_HIGH_PRIORITY:
2110 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
2111 gtk_widget_show (priv->priority_icon);
2112 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2113 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityHighMenu");
2115 case TNY_HEADER_FLAG_LOW_PRIORITY:
2116 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
2117 gtk_widget_show (priv->priority_icon);
2118 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2119 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityLowMenu");
2122 gtk_widget_hide (priv->priority_icon);
2123 priority_action = gtk_ui_manager_get_action (parent_priv->ui_manager,
2124 "/MenuBar/ToolsMenu/MessagePriorityMenu/MessagePriorityNormalMenu");
2127 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (priority_action), TRUE);
2128 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2133 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
2136 ModestMsgEditWindowPrivate *priv;
2137 gint current_format;
2139 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2141 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2143 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
2144 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
2146 if (current_format != file_format) {
2147 switch (file_format) {
2148 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
2149 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
2151 case MODEST_FILE_FORMAT_PLAIN_TEXT:
2155 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
2156 response = gtk_dialog_run (GTK_DIALOG (dialog));
2157 gtk_widget_destroy (dialog);
2158 if (response == GTK_RESPONSE_OK)
2159 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
2163 update_dimmed (window);
2168 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
2171 ModestMsgEditWindowPrivate *priv;
2172 WPTextBufferFormat oldfmt, fmt;
2173 gint old_position = 0;
2177 GdkColor *color = NULL;
2178 gboolean bold, bold_set, italic, italic_set;
2179 gboolean underline, underline_set;
2180 gboolean strikethrough, strikethrough_set;
2181 gboolean position_set;
2182 gboolean font_size_set, font_set, color_set;
2185 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2186 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2188 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2190 /* First we get the currently selected font information */
2191 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2192 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2194 switch (oldfmt.text_position) {
2195 case TEXT_POSITION_NORMAL:
2198 case TEXT_POSITION_SUPERSCRIPT:
2206 g_object_set (G_OBJECT (dialog),
2207 "bold", oldfmt.bold != FALSE,
2208 "bold-set", !oldfmt.cs.bold,
2209 "underline", oldfmt.underline != FALSE,
2210 "underline-set", !oldfmt.cs.underline,
2211 "italic", oldfmt.italic != FALSE,
2212 "italic-set", !oldfmt.cs.italic,
2213 "strikethrough", oldfmt.strikethrough != FALSE,
2214 "strikethrough-set", !oldfmt.cs.strikethrough,
2215 "color", &oldfmt.color,
2216 "color-set", !oldfmt.cs.color,
2217 "size", wp_font_size[oldfmt.font_size],
2218 "size-set", !oldfmt.cs.font_size,
2219 "position", old_position,
2220 "position-set", !oldfmt.cs.text_position,
2221 "family", wp_get_font_name (oldfmt.font),
2222 "family-set", !oldfmt.cs.font,
2225 gtk_widget_show_all (dialog);
2226 response = gtk_dialog_run (GTK_DIALOG (dialog));
2227 if (response == GTK_RESPONSE_OK) {
2229 g_object_get( dialog,
2231 "bold-set", &bold_set,
2232 "underline", &underline,
2233 "underline-set", &underline_set,
2235 "italic-set", &italic_set,
2236 "strikethrough", &strikethrough,
2237 "strikethrough-set", &strikethrough_set,
2239 "color-set", &color_set,
2241 "size-set", &font_size_set,
2242 "family", &font_name,
2243 "family-set", &font_set,
2244 "position", &position,
2245 "position-set", &position_set,
2250 if (response == GTK_RESPONSE_OK) {
2251 memset(&fmt, 0, sizeof(fmt));
2257 fmt.italic = italic;
2258 fmt.cs.italic = TRUE;
2260 if (underline_set) {
2261 fmt.underline = underline;
2262 fmt.cs.underline = TRUE;
2264 if (strikethrough_set) {
2265 fmt.strikethrough = strikethrough;
2266 fmt.cs.strikethrough = TRUE;
2271 ? TEXT_POSITION_NORMAL
2272 : ( ( position == 1 )
2273 ? TEXT_POSITION_SUPERSCRIPT
2274 : TEXT_POSITION_SUBSCRIPT );
2275 fmt.cs.text_position = TRUE;
2279 fmt.cs.color = TRUE;
2282 fmt.font = wp_get_font_index(font_name,
2287 if (font_size_set) {
2288 fmt.font_size = wp_get_font_size_index(
2289 font_size, DEFAULT_FONT_SIZE);
2290 fmt.cs.font_size = TRUE;
2292 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2294 gtk_widget_destroy (dialog);
2296 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2300 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2302 ModestMsgEditWindowPrivate *priv;
2304 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2305 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2307 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2309 update_dimmed (window);
2314 update_dimmed (ModestMsgEditWindow *window)
2316 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2317 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2321 gboolean editor_focused;
2323 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2324 editor_focused = gtk_widget_is_focus (priv->msg_body);
2326 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2327 gtk_action_set_sensitive (action, rich_text && editor_focused);
2328 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2329 gtk_action_set_sensitive (action, rich_text && editor_focused);
2330 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2331 gtk_action_set_sensitive (action, rich_text && editor_focused);
2332 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2333 gtk_action_set_sensitive (action, rich_text && editor_focused);
2334 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2335 gtk_action_set_sensitive (action, rich_text && editor_focused);
2336 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2337 gtk_action_set_sensitive (action, rich_text && editor_focused);
2338 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2339 gtk_action_set_sensitive (action, rich_text && editor_focused);
2340 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2341 gtk_action_set_sensitive (action, rich_text && editor_focused);
2342 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2343 gtk_action_set_sensitive (action, rich_text && editor_focused);
2344 widget = priv->font_color_button;
2345 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2346 widget = priv->font_size_toolitem;
2347 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2348 widget = priv->font_face_toolitem;
2349 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2353 setup_insensitive_handlers (ModestMsgEditWindow *window)
2355 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2356 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2359 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2360 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2361 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2362 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2364 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2365 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2366 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2367 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2368 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2369 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2370 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2371 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2372 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2373 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2374 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2375 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2376 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2377 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2378 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2379 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2380 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2381 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2382 widget = priv->font_color_button;
2383 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2384 widget = priv->font_size_toolitem;
2385 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2386 widget = priv->font_face_toolitem;
2387 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2389 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2390 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (remove_attachment_insensitive_press), window);
2391 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2392 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (zoom_insensitive_press), window);
2396 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2398 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2401 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2402 gtk_action_set_sensitive (action, can_undo);
2406 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2409 GtkTextIter match_start, match_end;
2411 if (image_id == NULL)
2414 gtk_text_buffer_get_start_iter (buffer, &iter);
2416 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2417 GSList *tags = gtk_text_iter_get_tags (&match_start);
2419 for (node = tags; node != NULL; node = g_slist_next (node)) {
2420 GtkTextTag *tag = (GtkTextTag *) node->data;
2421 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2422 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2423 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2425 offset = gtk_text_iter_get_offset (&match_start);
2426 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2427 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2431 gtk_text_iter_forward_char (&iter);
2436 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2438 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2439 GtkTextIter real_start, real_end;
2440 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2442 if (gtk_text_iter_compare (start, end) > 0) {
2446 real_start = *start;
2450 GSList *tags = gtk_text_iter_get_tags (&real_start);
2452 for (node = tags; node != NULL; node = g_slist_next (node)) {
2453 GtkTextTag *tag = (GtkTextTag *) node->data;
2454 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2455 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2457 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2459 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2462 } while (gtk_text_iter_forward_char (&real_start)&&
2463 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2467 msg_body_focus (GtkWidget *focus,
2468 GdkEventFocus *event,
2472 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2477 recpt_field_changed (GtkTextBuffer *buffer,
2478 ModestMsgEditWindow *editor)
2480 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2481 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2482 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2483 gboolean dim = FALSE;
2486 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2487 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2488 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2490 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2491 gtk_text_buffer_get_char_count (cc_buffer) +
2492 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2494 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2495 gtk_action_set_sensitive (action, !dim);
2496 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2497 gtk_action_set_sensitive (action, !dim);
2501 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2503 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2507 zoom_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2509 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2513 remove_attachment_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2515 ModestWindowPrivate *parent_priv;
2516 ModestMsgEditWindowPrivate *priv;
2517 GList *selected_attachments = NULL;
2518 gint n_att_selected = 0;
2520 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2521 parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2523 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2524 n_att_selected = g_list_length (selected_attachments);
2525 g_list_free (selected_attachments);
2527 if (n_att_selected > 1)
2528 hildon_banner_show_information (NULL, NULL, _("mcen_ib_unable_to_display_more"));
2529 else if (n_att_selected == 0)
2530 hildon_banner_show_information (NULL, NULL, _("TODO: select one attachment"));
2535 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2537 gboolean rich_text, editor_focused;
2539 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2540 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2541 editor_focused = gtk_widget_is_focus (priv->msg_body);
2544 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2545 else if (!editor_focused)
2546 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2550 reset_modified (ModestMsgEditWindow *editor)
2552 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2553 GtkTextBuffer *buffer;
2555 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2556 gtk_text_buffer_set_modified (buffer, FALSE);
2557 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2558 gtk_text_buffer_set_modified (buffer, FALSE);
2559 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2560 gtk_text_buffer_set_modified (buffer, FALSE);
2561 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2565 is_modified (ModestMsgEditWindow *editor)
2567 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2568 GtkTextBuffer *buffer;
2570 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2571 if (gtk_text_buffer_get_modified (buffer))
2573 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2574 if (gtk_text_buffer_get_modified (buffer))
2576 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2577 if (gtk_text_buffer_get_modified (buffer))
2579 if (gtk_text_buffer_get_modified (priv->text_buffer))
2586 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2588 ModestMsgEditWindowPrivate *priv = NULL;
2590 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2591 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2593 /* check if there's no recipient added */
2594 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2595 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2596 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2597 /* no recipient contents, then select contacts */
2598 modest_msg_edit_window_open_addressbook (window, NULL);
2602 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2604 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2606 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2609 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2616 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2617 ModestMsgEditWindow *window)
2619 modest_msg_edit_window_attach_file (window);
2623 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2625 ModestMsgEditWindow *window)
2627 ModestWindowPrivate *parent_priv;
2628 ModestMsgEditWindowPrivate *priv;
2632 GList *selected_attachments = NULL;
2633 gint n_att_selected = 0;
2635 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2636 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2637 selection = gtk_clipboard_wait_for_text (clipboard);
2638 focused = gtk_window_get_focus (GTK_WINDOW (window));
2640 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2641 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2642 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2643 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2645 selected_attachments = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
2646 n_att_selected = g_list_length (selected_attachments);
2647 g_list_free (selected_attachments);
2649 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/RemoveAttachmentsMenu");
2650 gtk_action_set_sensitive (action, n_att_selected == 1);
2653 update_paste_dimming (window);
2657 update_window_title (ModestMsgEditWindow *window)
2659 ModestMsgEditWindowPrivate *priv = NULL;
2660 const gchar *subject;
2662 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2663 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2664 if (subject == NULL || subject[0] == '\0')
2665 subject = _("mail_va_new_email");
2667 gtk_window_set_title (GTK_WINDOW (window), subject);
2672 subject_field_changed (GtkEditable *editable,
2673 ModestMsgEditWindow *window)
2675 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2676 update_window_title (window);
2677 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
2681 modest_msg_edit_window_toggle_find_toolbar (ModestMsgEditWindow *window,
2684 ModestMsgEditWindowPrivate *priv = NULL;
2686 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2687 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2689 gtk_widget_set_no_show_all (priv->find_toolbar, FALSE);
2691 gtk_widget_show_all (priv->find_toolbar);
2692 hildon_find_toolbar_highlight_entry (HILDON_FIND_TOOLBAR (priv->find_toolbar), TRUE);
2694 gtk_widget_hide_all (priv->find_toolbar);
2695 gtk_widget_grab_focus (priv->msg_body);
2701 modest_msg_edit_window_find_toolbar_search (GtkWidget *widget,
2702 ModestMsgEditWindow *window)
2704 gchar *current_search = NULL;
2705 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2707 GtkTextIter selection_start, selection_end;
2708 GtkTextIter match_start, match_end;
2710 g_object_get (G_OBJECT (widget), "prefix", ¤t_search, NULL);
2711 if ((current_search == NULL) && (strcmp (current_search, "") == 0)) {
2712 g_free (current_search);
2716 gtk_text_buffer_get_selection_bounds (priv->text_buffer, &selection_start, &selection_end);
2717 result = gtk_text_iter_forward_search (&selection_end, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, NULL);
2719 GtkTextIter buffer_start;
2720 gtk_text_buffer_get_start_iter (priv->text_buffer, &buffer_start);
2721 result = gtk_text_iter_forward_search (&buffer_start, current_search, GTK_TEXT_SEARCH_VISIBLE_ONLY, &match_start, &match_end, &selection_start);
2724 gtk_text_buffer_select_range (priv->text_buffer, &match_start, &match_end);
2725 gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (priv->msg_body), &match_start, 0.0, TRUE, 0.0, 0.0);
2727 /* TODO: warning about non succesful search */
2729 g_free (current_search);
2733 modest_msg_edit_window_find_toolbar_close (GtkWidget *widget,
2734 ModestMsgEditWindow *window)
2736 GtkToggleAction *toggle;
2737 ModestWindowPrivate *parent_priv;
2738 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2740 toggle = GTK_TOGGLE_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/FindInMessageMenu"));
2741 gtk_toggle_action_set_active (toggle, FALSE);
2746 update_paste_dimming (ModestMsgEditWindow *window)
2748 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2749 GtkAction *action = NULL;
2750 GtkClipboard *clipboard = NULL;
2752 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2754 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/PasteMenu");
2755 gtk_action_set_sensitive (action, gtk_clipboard_wait_is_text_available (clipboard));
2760 modest_msg_edit_window_system_clipboard_owner_change (GtkClipboard *clipboard,
2762 ModestMsgEditWindow *window)
2764 update_paste_dimming (window);
2768 update_select_all_dimming (ModestMsgEditWindow *window)
2771 gboolean dimmed = FALSE;
2773 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2775 focused = gtk_window_get_focus (GTK_WINDOW (window));
2776 if (GTK_IS_ENTRY (focused)) {
2777 const gchar *current_text;
2778 current_text = gtk_entry_get_text (GTK_ENTRY (focused));
2779 dimmed = ((current_text == NULL) || (current_text[0] == '\0'));
2780 } else if (GTK_IS_TEXT_VIEW (focused)) {
2781 GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused));
2782 dimmed = (gtk_text_buffer_get_char_count (buffer) < 1);
2783 } else if (MODEST_IS_ATTACHMENTS_VIEW (focused)) {
2786 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/SelectAllMenu");
2787 gtk_action_set_sensitive (action, !dimmed);
2791 update_zoom_dimming (ModestMsgEditWindow *window)
2794 gboolean dimmed = FALSE;
2796 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2798 focused = gtk_window_get_focus (GTK_WINDOW (window));
2799 dimmed = ! WP_IS_TEXT_VIEW (focused);
2800 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ZoomMenu");
2801 gtk_action_set_sensitive (action, !dimmed);
2805 edit_menu_activated (GtkAction *action,
2808 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2810 update_select_all_dimming (window);
2813 view_menu_activated (GtkAction *action,
2816 ModestMsgEditWindow *window = MODEST_MSG_EDIT_WINDOW (userdata);
2818 update_zoom_dimming (window);