1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37 #include <tny-vfs-stream.h>
41 #include <modest-account-mgr.h>
42 #include <modest-account-mgr-helpers.h>
44 #include <widgets/modest-msg-edit-window.h>
45 #include <widgets/modest-combo-box.h>
46 #include <widgets/modest-recpt-editor.h>
47 #include <widgets/modest-attachments-view.h>
49 #include <modest-runtime.h>
51 #include "modest-platform.h"
52 #include "modest-icon-names.h"
53 #include "modest-widget-memory.h"
54 #include "modest-window-priv.h"
55 #include "modest-mail-operation.h"
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-address-book.h"
59 #include "modest-text-utils.h"
60 #include <tny-simple-list.h>
61 #include <wptextview.h>
62 #include <wptextbuffer.h>
63 #include "modest-scroll-area.h"
65 #include "modest-hildon-includes.h"
66 #include "widgets/modest-msg-edit-window-ui.h"
67 #include <libgnomevfs/gnome-vfs-mime.h>
70 #define DEFAULT_FONT_SIZE 3
71 #define DEFAULT_FONT 2
72 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
73 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
74 #define DEFAULT_MAIN_VBOX_SPACING 6
75 #define SUBJECT_MAX_LENGTH 1000
77 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
78 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
79 static void modest_msg_edit_window_finalize (GObject *obj);
81 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
82 static void to_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
83 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
84 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
85 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
86 static void reset_modified (ModestMsgEditWindow *editor);
87 static gboolean is_modified (ModestMsgEditWindow *editor);
89 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
90 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
91 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
92 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
93 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
94 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
96 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
98 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
100 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
101 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
102 GdkEventWindowState *event,
104 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
105 ModestRecptEditor *editor);
106 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
107 ModestMsgEditWindow *window);
109 /* ModestWindow methods implementation */
110 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
111 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
112 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
113 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
114 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
115 gboolean show_toolbar);
116 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
118 ModestMsgEditWindow *window);
119 static void update_window_title (ModestMsgEditWindow *window);
120 static void update_dimmed (ModestMsgEditWindow *window);
123 /* list my signals */
130 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
131 struct _ModestMsgEditWindowPrivate {
133 GtkWidget *header_box;
135 ModestPairList *from_field_protos;
136 GtkWidget *from_field;
140 GtkWidget *bcc_field;
141 GtkWidget *subject_field;
142 GtkWidget *attachments_view;
143 GtkWidget *priority_icon;
144 GtkWidget *add_attachment_button;
146 GtkWidget *cc_caption;
147 GtkWidget *bcc_caption;
148 GtkWidget *attachments_caption;
150 GtkTextBuffer *text_buffer;
152 GtkWidget *font_size_toolitem;
153 GtkWidget *font_face_toolitem;
154 GtkWidget *font_color_button;
155 GSList *font_items_group;
156 GtkWidget *font_tool_button_label;
157 GSList *size_items_group;
158 GtkWidget *size_tool_button_label;
165 TnyHeaderFlags priority_flags;
169 gulong clipboard_change_handler_id;
174 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
175 MODEST_TYPE_MSG_EDIT_WINDOW, \
176 ModestMsgEditWindowPrivate))
178 static GtkWindowClass *parent_class = NULL;
180 /* uncomment the following if you have defined any signals */
181 /* static guint signals[LAST_SIGNAL] = {0}; */
184 modest_msg_edit_window_get_type (void)
186 static GType my_type = 0;
188 static const GTypeInfo my_info = {
189 sizeof(ModestMsgEditWindowClass),
190 NULL, /* base init */
191 NULL, /* base finalize */
192 (GClassInitFunc) modest_msg_edit_window_class_init,
193 NULL, /* class finalize */
194 NULL, /* class data */
195 sizeof(ModestMsgEditWindow),
197 (GInstanceInitFunc) modest_msg_edit_window_init,
200 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
201 "ModestMsgEditWindow",
204 wp_text_buffer_library_init ();
210 save_state (ModestWindow *self)
212 modest_widget_memory_save (modest_runtime_get_conf(),
213 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
218 restore_settings (ModestMsgEditWindow *self)
220 modest_widget_memory_restore (modest_runtime_get_conf(),
221 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
226 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
228 GObjectClass *gobject_class;
229 ModestWindowClass *modest_window_class;
230 gobject_class = (GObjectClass*) klass;
231 modest_window_class = (ModestWindowClass*) klass;
233 parent_class = g_type_class_peek_parent (klass);
234 gobject_class->finalize = modest_msg_edit_window_finalize;
236 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
237 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
238 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
239 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
240 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
242 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
244 modest_window_class->save_state_func = save_state;
248 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
250 ModestMsgEditWindowPrivate *priv;
251 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
253 priv->msg_body = NULL;
254 priv->from_field = NULL;
255 priv->to_field = NULL;
256 priv->cc_field = NULL;
257 priv->bcc_field = NULL;
258 priv->subject_field = NULL;
259 priv->attachments = NULL;
261 priv->zoom_level = 1.0;
263 priv->cc_caption = NULL;
264 priv->bcc_caption = NULL;
266 priv->priority_flags = 0;
268 priv->draft_msg = NULL;
269 priv->clipboard_change_handler_id = 0;
273 /* FIXME: this is a dup from the one in gtk/ */
276 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
278 static ModestPairList*
279 get_transports (void)
281 GSList *transports = NULL;
283 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
284 GSList *accounts = modest_account_mgr_account_names (account_mgr,
285 TRUE /* only enabled accounts. */);
287 GSList *cursor = accounts;
289 const gchar *account_name = cursor->data;
290 gchar *from_string = NULL;
292 from_string = modest_account_mgr_get_from_string (account_mgr,
296 if (from_string && account_name) {
297 gchar *name = g_strdup (account_name);
298 ModestPair *pair = modest_pair_new ((gpointer) name,
299 (gpointer) from_string , TRUE);
300 transports = g_slist_prepend (transports, pair);
303 cursor = cursor->next;
305 g_slist_free (accounts);
311 init_window (ModestMsgEditWindow *obj)
313 GtkWidget *from_caption, *to_caption, *subject_caption;
314 GtkWidget *main_vbox;
315 ModestMsgEditWindowPrivate *priv;
317 GtkSizeGroup *size_group;
319 GtkWidget *scroll_area;
320 GtkWidget *subject_box;
321 GtkWidget *attachment_icon;
323 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
325 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
327 /* Note: This ModestPairList* must exist for as long as the combo
328 * that uses it, because the ModestComboBox uses the ID opaquely,
329 * so it can't know how to manage its memory. */
330 priv->from_field_protos = get_transports ();
332 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
334 priv->to_field = modest_recpt_editor_new ();
335 priv->cc_field = modest_recpt_editor_new ();
336 priv->bcc_field = modest_recpt_editor_new ();
337 subject_box = gtk_hbox_new (FALSE, 0);
338 priv->priority_icon = gtk_image_new ();
339 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
340 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
341 g_object_set (G_OBJECT (priv->subject_field), "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
342 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
343 priv->add_attachment_button = gtk_button_new ();
344 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
345 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
346 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
347 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
348 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
349 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
350 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
351 priv->attachments_view = modest_attachments_view_new (NULL);
353 priv->header_box = gtk_vbox_new (FALSE, 0);
355 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
356 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
357 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
358 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
359 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
360 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
361 g_object_unref (size_group);
363 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
364 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
365 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
366 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
367 gtk_size_group_add_widget (size_group, priv->subject_field);
368 gtk_size_group_add_widget (size_group, priv->attachments_view);
369 g_object_unref (size_group);
371 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
372 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
373 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
374 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
375 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
376 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
377 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
380 priv->msg_body = wp_text_view_new ();
381 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
382 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
383 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
384 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
385 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
386 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
388 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
389 G_CALLBACK (text_buffer_refresh_attributes), obj);
390 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
391 G_CALLBACK (text_buffer_delete_range), obj);
392 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
393 G_CALLBACK (text_buffer_can_undo), obj);
394 g_signal_connect (G_OBJECT (obj), "window-state-event",
395 G_CALLBACK (modest_msg_edit_window_window_state_event),
397 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
398 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
399 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
400 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
401 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
402 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
404 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
405 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
407 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
408 G_CALLBACK (msg_body_focus), obj);
409 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
410 G_CALLBACK (msg_body_focus), obj);
411 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
412 "changed", G_CALLBACK (to_field_changed), obj);
413 to_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
414 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
416 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
417 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
418 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
420 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
422 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
423 frame = gtk_frame_new (NULL);
424 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
426 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
427 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
428 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
430 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL))
431 gtk_widget_hide (priv->cc_field);
432 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL))
433 gtk_widget_hide (priv->bcc_field);
435 gtk_container_add (GTK_CONTAINER(obj), priv->scroll);
436 scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
437 gtk_container_add (GTK_CONTAINER (frame), scroll_area);
438 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
439 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
441 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
442 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
448 modest_msg_edit_window_finalize (GObject *obj)
450 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
453 if (priv->clipboard_change_handler_id > 0) {
454 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
455 priv->clipboard_change_handler_id = 0;
458 /* This had to stay alive for as long as the combobox that used it: */
459 modest_pair_list_free (priv->from_field_protos);
461 G_OBJECT_CLASS(parent_class)->finalize (obj);
465 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
467 GtkWidget *close_dialog;
468 ModestMsgEditWindowPrivate *priv;
471 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
472 modest_window_save_state (MODEST_WINDOW (self));
473 if (is_modified (self)) {
474 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
475 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
476 gtk_widget_destroy (close_dialog);
478 if (response != GTK_RESPONSE_CANCEL) {
479 modest_ui_actions_on_save_to_drafts (NULL, self);
482 /* /\* remove old message from drafts *\/ */
483 /* if (priv->draft_msg) { */
484 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
485 /* TnyAccount *account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(), */
487 /* TNY_ACCOUNT_TYPE_STORE); */
488 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
489 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
490 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
491 /* tny_folder_remove_msg (folder, header, NULL); */
492 /* g_object_unref (folder); */
493 /* g_object_unref (header); */
494 /* g_object_unref (priv->draft_msg); */
495 /* priv->draft_msg = NULL; */
497 gtk_widget_destroy (GTK_WIDGET (self));
503 menubar_to_menu (GtkUIManager *ui_manager)
505 GtkWidget *main_menu;
509 /* Create new main menu */
510 main_menu = gtk_menu_new();
512 /* Get the menubar from the UI manager */
513 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
515 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
519 menu = GTK_WIDGET (iter->data);
520 gtk_widget_reparent(menu, main_menu);
522 iter = g_list_next (iter);
529 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
532 const gchar *to, *cc, *bcc, *subject;
534 ModestMsgEditWindowPrivate *priv;
537 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
538 g_return_if_fail (TNY_IS_MSG (msg));
540 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
542 header = tny_msg_get_header (msg);
543 to = tny_header_get_to (header);
544 cc = tny_header_get_cc (header);
545 bcc = tny_header_get_bcc (header);
546 subject = tny_header_get_subject (header);
549 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
551 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
553 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
555 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
557 update_window_title (self);
559 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
560 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
561 body = modest_tny_msg_get_body (msg, TRUE);
563 if ((body == NULL)||(body[0] == '\0')) {
565 body = modest_text_utils_convert_to_html ("");
567 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
568 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
571 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
574 /* Get the default format required from configuration */
575 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
576 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
579 /* Set the default focus depending on having already a To: field or not */
580 if ((!to)||(*to == '\0')) {
581 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
583 gtk_widget_grab_focus (priv->msg_body);
586 /* TODO: lower priority, select in the From: combo to the
587 value that comes from msg <- not sure, should it be
590 /* Add attachments to the view */
591 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
592 if (priv->attachments == NULL)
593 gtk_widget_hide_all (priv->attachments_caption);
595 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
596 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
598 reset_modified (self);
600 update_dimmed (self);
601 text_buffer_can_undo (priv->text_buffer, FALSE, self);
603 priv->draft_msg = msg;
607 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
610 GList *item_children, *node;
611 GtkWidget *bin_child;
613 bin_child = gtk_bin_get_child (GTK_BIN(item));
615 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
617 for (node = item_children; node != NULL; node = g_list_next (node)) {
618 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
619 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
622 g_list_free (item_children);
626 menu_tool_button_dont_expand (GtkMenuToolButton *item)
629 GList *item_children, *node;
631 box = gtk_bin_get_child (GTK_BIN (item));
632 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
633 item_children = gtk_container_get_children (GTK_CONTAINER (box));
635 for (node = item_children; node != NULL; node = g_list_next (node)) {
636 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
637 if (GTK_IS_TOGGLE_BUTTON (node->data))
638 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
639 else if (GTK_IS_BUTTON (node->data))
640 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
642 g_list_free (item_children);
647 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
649 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
650 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
651 GtkWidget *placeholder;
652 GtkWidget *tool_item;
657 GtkWidget *sizes_menu;
658 GtkWidget *fonts_menu;
659 GSList *radio_group = NULL;
664 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
665 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
667 /* should we hide the toolbar? */
668 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
669 gtk_widget_hide (parent_priv->toolbar);
671 /* Font color placeholder */
672 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
673 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
676 tool_item = GTK_WIDGET (gtk_tool_item_new ());
677 priv->font_color_button = hildon_color_button_new ();
678 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
679 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
680 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
681 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
682 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
683 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
684 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
686 /* Font size and face placeholder */
687 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
688 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
690 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
691 priv->size_tool_button_label = gtk_label_new (NULL);
692 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
693 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
694 size_text,"</span>", NULL);
695 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
697 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
698 sizes_menu = gtk_menu_new ();
699 priv->size_items_group = NULL;
701 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
702 GtkWidget *size_menu_item;
704 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
705 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
706 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
707 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
708 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
709 gtk_widget_show (size_menu_item);
711 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
715 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
716 GtkWidget *item = (GtkWidget *) node->data;
717 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
721 priv->size_items_group = g_slist_reverse (priv->size_items_group);
722 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
723 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
724 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
725 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
726 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
727 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
728 priv->font_size_toolitem = tool_item;
731 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
732 priv->font_tool_button_label = gtk_label_new (NULL);
733 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
734 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
736 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
737 fonts_menu = gtk_menu_new ();
738 priv->font_items_group = NULL;
740 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
741 GtkWidget *font_menu_item;
742 GtkWidget *child_label;
744 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
745 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
746 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
747 wp_get_font_name (font_index), "</span>", NULL);
748 gtk_label_set_markup (GTK_LABEL (child_label), markup);
751 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
752 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
753 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
754 gtk_widget_show (font_menu_item);
756 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
759 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
760 GtkWidget *item = (GtkWidget *) node->data;
761 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
764 priv->font_items_group = g_slist_reverse (priv->font_items_group);
765 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
766 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
767 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
768 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
769 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
770 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
771 priv->font_face_toolitem = tool_item;
773 /* Set expand and homogeneous for remaining items */
774 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
775 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
776 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
777 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
778 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
779 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
780 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
781 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
782 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
790 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
793 ModestWindowPrivate *parent_priv;
794 ModestMsgEditWindowPrivate *priv;
795 GtkActionGroup *action_group;
796 GError *error = NULL;
797 GdkPixbuf *window_icon = NULL;
800 gboolean prefer_formatted;
803 g_return_val_if_fail (msg, NULL);
805 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
807 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
808 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
810 parent_priv->ui_manager = gtk_ui_manager_new();
811 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
812 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
814 /* Add common actions */
815 gtk_action_group_add_actions (action_group,
816 modest_msg_edit_action_entries,
817 G_N_ELEMENTS (modest_msg_edit_action_entries),
819 gtk_action_group_add_toggle_actions (action_group,
820 modest_msg_edit_toggle_action_entries,
821 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
823 gtk_action_group_add_radio_actions (action_group,
824 modest_msg_edit_alignment_radio_action_entries,
825 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
827 G_CALLBACK (modest_ui_actions_on_change_justify),
829 gtk_action_group_add_radio_actions (action_group,
830 modest_msg_edit_zoom_action_entries,
831 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
833 G_CALLBACK (modest_ui_actions_on_change_zoom),
835 gtk_action_group_add_radio_actions (action_group,
836 modest_msg_edit_priority_action_entries,
837 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
839 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
841 gtk_action_group_add_radio_actions (action_group,
842 modest_msg_edit_file_format_action_entries,
843 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
844 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
845 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
847 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
848 g_object_unref (action_group);
850 /* Load the UI definition */
851 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml", &error);
853 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
854 g_clear_error (&error);
857 /* Add accelerators */
858 gtk_window_add_accel_group (GTK_WINDOW (obj),
859 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
862 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
863 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
866 init_window (MODEST_MSG_EDIT_WINDOW(obj));
868 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
870 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
872 g_signal_connect (G_OBJECT(obj), "delete-event",
873 G_CALLBACK(on_delete_event), obj);
875 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
877 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
879 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
881 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
883 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
885 /* Set window icon */
886 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
887 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
889 /* Dim at start clipboard actions */
890 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
891 gtk_action_set_sensitive (action, FALSE);
892 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
893 gtk_action_set_sensitive (action, FALSE);
895 /* Setup the file format */
896 conf = modest_runtime_get_conf ();
897 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
899 g_clear_error (&error);
900 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
902 file_format = (prefer_formatted) ?
903 MODEST_FILE_FORMAT_FORMATTED_TEXT :
904 MODEST_FILE_FORMAT_PLAIN_TEXT;
905 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
907 return (ModestWindow*) obj;
911 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
913 GString **string_buffer = (GString **) user_data;
915 *string_buffer = g_string_append (*string_buffer, buffer);
921 * @result: A new string which should be freed with g_free().
924 get_formatted_data (ModestMsgEditWindow *edit_window)
926 ModestMsgEditWindowPrivate *priv;
927 GString *string_buffer = g_string_new ("");
929 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
931 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
933 return g_string_free (string_buffer, FALSE);
938 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
941 const gchar *account_name;
942 ModestMsgEditWindowPrivate *priv;
944 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
946 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
948 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
949 g_return_val_if_fail (account_name, NULL);
952 /* don't free these (except from) */
953 data = g_slice_new0 (MsgData);
954 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
956 data->account_name = g_strdup (account_name);
957 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
958 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
959 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
960 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
961 if (priv->draft_msg) {
962 data->draft_msg = g_object_ref (priv->draft_msg);
964 data->draft_msg = NULL;
967 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
969 gtk_text_buffer_get_bounds (buf, &b, &e);
970 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
972 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
973 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
975 data->html_body = NULL;
977 data->attachments = priv->attachments; /* TODO: copy and free ? */
978 data->priority_flags = priv->priority_flags;
983 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
985 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
988 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
996 g_free (data->subject);
997 g_free (data->plain_body);
998 g_free (data->html_body);
999 if (data->draft_msg != NULL) {
1000 g_object_unref (data->draft_msg);
1001 data->draft_msg = NULL;
1003 g_free (data->account_name);
1005 /* TODO: Free data->attachments? */
1007 g_slice_free (MsgData, data);
1011 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1014 ModestMsgEditWindowPrivate *priv = NULL;
1015 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1017 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1019 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1021 return MODEST_MSG_EDIT_FORMAT_HTML;
1023 return MODEST_MSG_EDIT_FORMAT_TEXT;
1027 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1028 ModestMsgEditFormat format)
1030 ModestMsgEditWindowPrivate *priv;
1032 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1033 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1036 case MODEST_MSG_EDIT_FORMAT_HTML:
1037 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1039 case MODEST_MSG_EDIT_FORMAT_TEXT:
1040 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1043 g_return_if_reached ();
1047 ModestMsgEditFormatState *
1048 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1050 ModestMsgEditFormatState *format_state = NULL;
1051 ModestMsgEditWindowPrivate *priv;
1052 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1054 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1055 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1057 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1059 format_state = g_new0 (ModestMsgEditFormatState, 1);
1060 format_state->bold = buffer_format->bold&0x1;
1061 format_state->italics = buffer_format->italic&0x1;
1062 format_state->bullet = buffer_format->bullet&0x1;
1063 format_state->color = buffer_format->color;
1064 format_state->font_size = buffer_format->font_size;
1065 format_state->font_family = wp_get_font_name (buffer_format->font);
1066 format_state->justification = buffer_format->justification;
1067 g_free (buffer_format);
1069 return format_state;
1074 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1075 const ModestMsgEditFormatState *format_state)
1077 ModestMsgEditWindowPrivate *priv;
1078 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1079 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1080 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1081 g_return_if_fail (format_state != NULL);
1083 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1084 gtk_widget_grab_focus (priv->msg_body);
1085 buffer_format->bold = (format_state->bold != FALSE);
1086 buffer_format->italic = (format_state->italics != FALSE);
1087 buffer_format->color = format_state->color;
1088 buffer_format->font_size = format_state->font_size;
1089 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1090 buffer_format->justification = format_state->justification;
1091 buffer_format->bullet = format_state->bullet;
1093 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1095 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1096 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1097 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1098 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1099 buffer_format->cs.font = (buffer_format->font != current_format->font);
1100 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1101 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1103 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1104 if (buffer_format->cs.bold) {
1105 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1107 if (buffer_format->cs.italic) {
1108 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1110 if (buffer_format->cs.color) {
1111 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1113 if (buffer_format->cs.font_size) {
1114 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1116 if (buffer_format->cs.justification) {
1117 switch (buffer_format->justification) {
1118 case GTK_JUSTIFY_LEFT:
1119 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1121 case GTK_JUSTIFY_CENTER:
1122 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1124 case GTK_JUSTIFY_RIGHT:
1125 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1132 if (buffer_format->cs.font) {
1133 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1135 if (buffer_format->cs.bullet) {
1136 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
1138 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1139 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1141 g_free (current_format);
1146 toggle_action_set_active_block_notify (GtkToggleAction *action,
1149 GSList *proxies = NULL;
1151 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1152 proxies != NULL; proxies = g_slist_next (proxies)) {
1153 GtkWidget *widget = (GtkWidget *) proxies->data;
1154 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1157 gtk_toggle_action_set_active (action, value);
1159 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1160 proxies != NULL; proxies = g_slist_next (proxies)) {
1161 GtkWidget *widget = (GtkWidget *) proxies->data;
1162 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1167 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1169 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1171 ModestWindowPrivate *parent_priv;
1172 ModestMsgEditWindowPrivate *priv;
1173 GtkWidget *new_size_menuitem;
1174 GtkWidget *new_font_menuitem;
1176 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1177 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1179 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1180 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1181 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1182 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1184 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1185 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1186 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1189 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1191 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1192 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1194 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1195 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1197 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1198 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1200 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1201 G_CALLBACK (modest_msg_edit_window_color_button_change),
1203 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1204 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1205 G_CALLBACK (modest_msg_edit_window_color_button_change),
1208 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1209 buffer_format->font_size))->data);
1210 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1214 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1215 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1216 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1218 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1219 G_CALLBACK (modest_msg_edit_window_size_change),
1221 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1222 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1223 G_CALLBACK (modest_msg_edit_window_size_change),
1227 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1228 buffer_format->font))->data);
1229 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1233 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1234 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1235 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1237 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1238 G_CALLBACK (modest_msg_edit_window_font_change),
1240 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1241 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1242 G_CALLBACK (modest_msg_edit_window_font_change),
1246 g_free (buffer_format);
1252 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1255 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1256 ModestMsgEditWindowPrivate *priv;
1257 GtkWidget *dialog = NULL;
1259 const GdkColor *new_color = NULL;
1261 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1262 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1264 #ifdef MODEST_HILDON_VERSION_0
1265 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1266 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1268 dialog = hildon_color_chooser_new ();
1269 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1270 #endif /*MODEST_HILDON_VERSION_0*/
1271 g_free (buffer_format);
1273 response = gtk_dialog_run (GTK_DIALOG (dialog));
1275 case GTK_RESPONSE_OK: {
1276 #ifdef MODEST_HILDON_VERSION_0
1277 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1280 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1282 #endif /*MODEST_HILDON_VERSION_0*/
1289 gtk_widget_destroy (dialog);
1291 if (new_color != NULL)
1292 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1297 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1300 ModestMsgEditWindowPrivate *priv;
1301 GtkWidget *dialog = NULL;
1303 GdkColor *old_color = NULL;
1304 const GdkColor *new_color = NULL;
1306 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1307 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1309 #ifdef MODEST_HILDON_VERSION_0
1310 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1311 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1313 dialog = hildon_color_chooser_new ();
1314 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1315 #endif /*MODEST_HILDON_VERSION_9*/
1317 response = gtk_dialog_run (GTK_DIALOG (dialog));
1319 case GTK_RESPONSE_OK: {
1320 #ifdef MODEST_HILDON_VERSION_0
1321 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1324 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1326 #endif /*MODEST_HILDON_VERSION_0*/
1332 gtk_widget_destroy (dialog);
1334 if (new_color != NULL)
1335 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1340 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1343 ModestMsgEditWindowPrivate *priv;
1344 GtkWidget *dialog = NULL;
1346 gchar *filename = NULL;
1348 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1350 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1352 response = gtk_dialog_run (GTK_DIALOG (dialog));
1354 case GTK_RESPONSE_OK:
1355 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1360 gtk_widget_destroy (dialog);
1363 GdkPixbuf *pixbuf = NULL;
1364 GtkTextIter position;
1365 GtkTextMark *insert_mark;
1367 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1370 GdkPixbufFormat *pixbuf_format;
1372 image_file_id = g_open (filename, O_RDONLY, 0);
1373 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1374 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1375 TnyMimePart *image_part;
1376 TnyStream *image_stream;
1382 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1383 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1384 mime_type = mime_types[0];
1386 mime_type = "image/unknown";
1388 image_part = tny_platform_factory_new_mime_part
1389 (modest_runtime_get_platform_factory ());
1390 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1392 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1393 g_strfreev (mime_types);
1395 content_id = g_strdup_printf ("%d", priv->last_cid);
1396 tny_mime_part_set_content_id (image_part, content_id);
1397 g_free (content_id);
1400 basename = g_path_get_basename (filename);
1401 tny_mime_part_set_filename (image_part, basename);
1404 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1405 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1406 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1407 priv->attachments = g_list_prepend (priv->attachments, image_part);
1408 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1410 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1411 gtk_widget_show_all (priv->attachments_caption);
1412 } else if (image_file_id == -1) {
1413 close (image_file_id);
1422 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1425 ModestMsgEditWindowPrivate *priv;
1426 GtkWidget *dialog = NULL;
1428 gchar *uri = NULL, *filename = NULL;
1430 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1432 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1434 response = gtk_dialog_run (GTK_DIALOG (dialog));
1436 case GTK_RESPONSE_OK:
1437 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
1438 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1443 gtk_widget_destroy (dialog);
1447 GnomeVFSHandle *handle = NULL;
1448 GnomeVFSResult result;
1450 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1451 if (result == GNOME_VFS_OK) {
1452 TnyMimePart *mime_part;
1454 const gchar *mime_type = NULL;
1457 GnomeVFSFileInfo info;
1459 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1460 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1461 mime_part = tny_platform_factory_new_mime_part
1462 (modest_runtime_get_platform_factory ());
1463 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1465 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1467 content_id = g_strdup_printf ("%d", priv->last_cid);
1468 tny_mime_part_set_content_id (mime_part, content_id);
1469 g_free (content_id);
1472 basename = g_path_get_basename (filename);
1473 tny_mime_part_set_filename (mime_part, basename);
1476 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1477 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1479 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1480 gtk_widget_show_all (priv->attachments_caption);
1487 modest_msg_edit_window_attach_file_noninteractive (
1488 ModestMsgEditWindow *window,
1492 ModestMsgEditWindowPrivate *priv;
1494 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1499 file_id = g_open (filename, O_RDONLY, 0);
1500 if (file_id != -1) {
1501 TnyMimePart *mime_part;
1503 const gchar *mime_type;
1507 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1508 mime_part = tny_platform_factory_new_mime_part
1509 (modest_runtime_get_platform_factory ());
1510 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1512 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1514 content_id = g_strdup_printf ("%d", priv->last_cid);
1515 tny_mime_part_set_content_id (mime_part, content_id);
1516 g_free (content_id);
1519 basename = g_path_get_basename (filename);
1520 tny_mime_part_set_filename (mime_part, basename);
1523 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1524 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1526 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1527 gtk_widget_show_all (priv->attachments_caption);
1528 } else if (file_id == -1) {
1535 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1538 ModestMsgEditWindowPrivate *priv;
1539 gboolean clean_list = FALSE;
1541 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1542 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1544 if (att_list == NULL) {
1545 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1549 if (att_list == NULL) {
1550 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1552 GtkWidget *confirmation_dialog = NULL;
1553 gboolean dialog_response;
1555 if (att_list->next == NULL) {
1556 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1557 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1558 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1561 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1563 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1564 gtk_widget_destroy (confirmation_dialog);
1565 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1567 for (node = att_list; node != NULL; node = g_list_next (node)) {
1568 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1569 const gchar *att_id;
1570 priv->attachments = g_list_remove (priv->attachments, mime_part);
1572 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1574 att_id = tny_mime_part_get_content_id (mime_part);
1576 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1578 g_object_unref (mime_part);
1583 g_list_free (att_list);
1587 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1590 ModestMsgEditWindowPrivate *priv;
1591 GdkColor *new_color;
1592 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1594 #ifdef MODEST_HILDON_VERSION_0
1595 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1598 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1600 #endif /*MODEST_HILDON_VERSION_0*/
1602 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1604 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1609 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1612 ModestMsgEditWindowPrivate *priv;
1613 gint new_size_index;
1614 ModestMsgEditWindow *window;
1617 window = MODEST_MSG_EDIT_WINDOW (userdata);
1618 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1619 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1621 if (gtk_check_menu_item_get_active (menu_item)) {
1623 WPTextBufferFormat format;
1625 label = gtk_bin_get_child (GTK_BIN (menu_item));
1627 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1628 memset (&format, 0, sizeof (format));
1629 format.cs.font_size = TRUE;
1630 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1631 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1633 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1634 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1635 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1637 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1638 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1639 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1645 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1648 ModestMsgEditWindowPrivate *priv;
1649 gint new_font_index;
1650 ModestMsgEditWindow *window;
1653 window = MODEST_MSG_EDIT_WINDOW (userdata);
1654 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1655 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1657 if (gtk_check_menu_item_get_active (menu_item)) {
1660 label = gtk_bin_get_child (GTK_BIN (menu_item));
1662 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1664 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1665 (gpointer) new_font_index))
1666 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1668 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1669 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1670 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1676 modest_msg_edit_window_set_zoom (ModestWindow *window,
1679 ModestMsgEditWindowPrivate *priv;
1681 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1683 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1684 priv->zoom_level = zoom;
1685 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1689 modest_msg_edit_window_get_zoom (ModestWindow *window)
1691 ModestMsgEditWindowPrivate *priv;
1693 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1695 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1696 return priv->zoom_level;
1700 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1702 ModestWindowPrivate *parent_priv;
1703 GtkRadioAction *zoom_radio_action;
1704 GSList *group, *node;
1706 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1707 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1708 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1710 group = gtk_radio_action_get_group (zoom_radio_action);
1712 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1713 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1717 for (node = group; node != NULL; node = g_slist_next (node)) {
1718 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1719 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1727 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1729 ModestWindowPrivate *parent_priv;
1730 GtkRadioAction *zoom_radio_action;
1731 GSList *group, *node;
1733 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1734 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1735 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1737 group = gtk_radio_action_get_group (zoom_radio_action);
1739 for (node = group; node != NULL; node = g_slist_next (node)) {
1740 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1741 if (node->next != NULL) {
1742 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1745 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1753 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1755 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1756 ModestWindowPrivate *parent_priv;
1757 ModestWindowMgr *mgr;
1758 gboolean is_fullscreen;
1759 GtkAction *fs_toggle_action;
1762 mgr = modest_runtime_get_window_mgr ();
1763 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1765 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1767 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1768 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1769 if (is_fullscreen != active)
1770 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1778 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1780 ModestWindowPrivate *parent_priv;
1781 GtkAction *fs_toggle_action;
1784 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1786 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1787 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1788 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1792 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1795 ModestMsgEditWindowPrivate *priv = NULL;
1796 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1798 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1800 gtk_widget_show (priv->cc_caption);
1802 gtk_widget_hide (priv->cc_caption);
1806 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1809 ModestMsgEditWindowPrivate *priv = NULL;
1810 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1812 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1814 gtk_widget_show (priv->bcc_caption);
1816 gtk_widget_hide (priv->bcc_caption);
1820 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1821 ModestRecptEditor *editor)
1823 ModestMsgEditWindowPrivate *priv;
1825 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1826 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1827 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1829 if (editor == NULL) {
1830 GtkWidget *view_focus;
1831 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1833 /* This code should be kept in sync with ModestRecptEditor. The
1834 textview inside the recpt editor is the one that really gets the
1835 focus. As it's inside a scrolled window, and this one inside the
1836 hbox recpt editor inherits from, we'll need to go up in the
1837 hierarchy to know if the text view is part of the recpt editor
1838 or if it's a different text entry */
1840 if (gtk_widget_get_parent (view_focus)) {
1841 GtkWidget *first_parent;
1843 first_parent = gtk_widget_get_parent (view_focus);
1844 if (gtk_widget_get_parent (first_parent) &&
1845 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1846 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1851 editor = MODEST_RECPT_EDITOR (priv->to_field);
1855 modest_address_book_select_addresses (editor);
1860 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1862 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1864 modest_msg_edit_window_open_addressbook (window, NULL);
1868 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1869 gboolean show_toolbar)
1871 ModestWindowPrivate *parent_priv;
1873 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1874 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1876 /* FIXME: we can not just use the code of
1877 modest_msg_edit_window_setup_toolbar because it has a
1878 mixture of both initialization and creation code. */
1881 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1883 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1887 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1888 TnyHeaderFlags priority_flags)
1890 ModestMsgEditWindowPrivate *priv;
1892 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1894 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1895 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1897 if (priv->priority_flags != priority_flags) {
1899 priv->priority_flags = priority_flags;
1901 switch (priority_flags) {
1902 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1903 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1904 gtk_widget_show (priv->priority_icon);
1906 case TNY_HEADER_FLAG_LOW_PRIORITY:
1907 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1908 gtk_widget_show (priv->priority_icon);
1911 gtk_widget_hide (priv->priority_icon);
1918 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1921 ModestMsgEditWindowPrivate *priv;
1922 gint current_format;
1924 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1926 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1928 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1929 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1931 if (current_format != file_format) {
1932 switch (file_format) {
1933 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1934 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1936 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1940 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1941 response = gtk_dialog_run (GTK_DIALOG (dialog));
1942 gtk_widget_destroy (dialog);
1943 if (response == GTK_RESPONSE_OK)
1944 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1948 update_dimmed (window);
1953 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1956 ModestMsgEditWindowPrivate *priv;
1957 WPTextBufferFormat oldfmt, fmt;
1958 gint old_position = 0;
1962 GdkColor *color = NULL;
1963 gboolean bold, bold_set, italic, italic_set;
1964 gboolean underline, underline_set;
1965 gboolean strikethrough, strikethrough_set;
1966 gboolean position_set;
1967 gboolean font_size_set, font_set, color_set;
1970 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1971 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1973 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
1975 /* First we get the currently selected font information */
1976 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
1977 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
1979 switch (oldfmt.text_position) {
1980 case TEXT_POSITION_NORMAL:
1983 case TEXT_POSITION_SUPERSCRIPT:
1991 g_object_set (G_OBJECT (dialog),
1992 "bold", oldfmt.bold != FALSE,
1993 "bold-set", !oldfmt.cs.bold,
1994 "underline", oldfmt.underline != FALSE,
1995 "underline-set", !oldfmt.cs.underline,
1996 "italic", oldfmt.italic != FALSE,
1997 "italic-set", !oldfmt.cs.italic,
1998 "strikethrough", oldfmt.strikethrough != FALSE,
1999 "strikethrough-set", !oldfmt.cs.strikethrough,
2000 "color", &oldfmt.color,
2001 "color-set", !oldfmt.cs.color,
2002 "size", wp_font_size[oldfmt.font_size],
2003 "size-set", !oldfmt.cs.font_size,
2004 "position", old_position,
2005 "position-set", !oldfmt.cs.text_position,
2006 "family", wp_get_font_name (oldfmt.font),
2007 "family-set", !oldfmt.cs.font,
2010 gtk_widget_show_all (dialog);
2011 response = gtk_dialog_run (GTK_DIALOG (dialog));
2012 if (response == GTK_RESPONSE_OK) {
2014 g_object_get( dialog,
2016 "bold-set", &bold_set,
2017 "underline", &underline,
2018 "underline-set", &underline_set,
2020 "italic-set", &italic_set,
2021 "strikethrough", &strikethrough,
2022 "strikethrough-set", &strikethrough_set,
2024 "color-set", &color_set,
2026 "size-set", &font_size_set,
2027 "family", &font_name,
2028 "family-set", &font_set,
2029 "position", &position,
2030 "position-set", &position_set,
2035 if (response == GTK_RESPONSE_OK) {
2036 memset(&fmt, 0, sizeof(fmt));
2042 fmt.italic = italic;
2043 fmt.cs.italic = TRUE;
2045 if (underline_set) {
2046 fmt.underline = underline;
2047 fmt.cs.underline = TRUE;
2049 if (strikethrough_set) {
2050 fmt.strikethrough = strikethrough;
2051 fmt.cs.strikethrough = TRUE;
2056 ? TEXT_POSITION_NORMAL
2057 : ( ( position == 1 )
2058 ? TEXT_POSITION_SUPERSCRIPT
2059 : TEXT_POSITION_SUBSCRIPT );
2060 fmt.cs.text_position = TRUE;
2064 fmt.cs.color = TRUE;
2067 fmt.font = wp_get_font_index(font_name,
2072 if (font_size_set) {
2073 fmt.font_size = wp_get_font_size_index(
2074 font_size, DEFAULT_FONT_SIZE);
2075 fmt.cs.font_size = TRUE;
2077 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2079 gtk_widget_destroy (dialog);
2081 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2085 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2087 ModestMsgEditWindowPrivate *priv;
2089 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2090 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2092 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2094 update_dimmed (window);
2099 update_dimmed (ModestMsgEditWindow *window)
2101 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2102 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2106 gboolean editor_focused;
2108 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2109 editor_focused = gtk_widget_is_focus (priv->msg_body);
2111 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2112 gtk_action_set_sensitive (action, rich_text && editor_focused);
2113 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2114 gtk_action_set_sensitive (action, rich_text && editor_focused);
2115 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2116 gtk_action_set_sensitive (action, rich_text && editor_focused);
2117 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2118 gtk_action_set_sensitive (action, rich_text && editor_focused);
2119 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2120 gtk_action_set_sensitive (action, rich_text && editor_focused);
2121 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2122 gtk_action_set_sensitive (action, rich_text && editor_focused);
2123 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2124 gtk_action_set_sensitive (action, rich_text && editor_focused);
2125 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2126 gtk_action_set_sensitive (action, rich_text && editor_focused);
2127 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2128 gtk_action_set_sensitive (action, rich_text && editor_focused);
2129 widget = priv->font_color_button;
2130 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2131 widget = priv->font_size_toolitem;
2132 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2133 widget = priv->font_face_toolitem;
2134 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2138 setup_insensitive_handlers (ModestMsgEditWindow *window)
2140 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2141 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2144 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2145 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2146 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2147 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2149 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2150 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2151 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2152 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2153 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2154 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2155 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2156 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2157 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2158 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2159 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2160 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2161 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2162 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2163 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2164 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2165 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2166 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2167 widget = priv->font_color_button;
2168 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2169 widget = priv->font_size_toolitem;
2170 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2171 widget = priv->font_face_toolitem;
2172 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2177 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2179 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2182 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2183 gtk_action_set_sensitive (action, can_undo);
2187 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2190 GtkTextIter match_start, match_end;
2192 if (image_id == NULL)
2195 gtk_text_buffer_get_start_iter (buffer, &iter);
2197 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2198 GSList *tags = gtk_text_iter_get_tags (&match_start);
2200 for (node = tags; node != NULL; node = g_slist_next (node)) {
2201 GtkTextTag *tag = (GtkTextTag *) node->data;
2202 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2203 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2204 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2206 offset = gtk_text_iter_get_offset (&match_start);
2207 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2208 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2212 gtk_text_iter_forward_char (&iter);
2217 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2219 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2220 GtkTextIter real_start, real_end;
2221 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2223 if (gtk_text_iter_compare (start, end) > 0) {
2227 real_start = *start;
2231 GSList *tags = gtk_text_iter_get_tags (&real_start);
2233 for (node = tags; node != NULL; node = g_slist_next (node)) {
2234 GtkTextTag *tag = (GtkTextTag *) node->data;
2235 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2236 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2238 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2240 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2243 } while (gtk_text_iter_forward_char (&real_start)&&
2244 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2248 msg_body_focus (GtkWidget *focus,
2249 GdkEventFocus *event,
2253 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2258 to_field_changed (GtkTextBuffer *buffer,
2259 ModestMsgEditWindow *editor)
2261 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2264 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2265 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2266 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2267 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2271 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2273 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2277 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2279 gboolean rich_text, editor_focused;
2281 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2282 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2283 editor_focused = gtk_widget_is_focus (priv->msg_body);
2286 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2287 else if (!editor_focused)
2288 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2292 reset_modified (ModestMsgEditWindow *editor)
2294 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2295 GtkTextBuffer *buffer;
2297 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2298 gtk_text_buffer_set_modified (buffer, FALSE);
2299 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2300 gtk_text_buffer_set_modified (buffer, FALSE);
2301 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2302 gtk_text_buffer_set_modified (buffer, FALSE);
2303 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2307 is_modified (ModestMsgEditWindow *editor)
2309 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2310 GtkTextBuffer *buffer;
2312 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2313 if (gtk_text_buffer_get_modified (buffer))
2315 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2316 if (gtk_text_buffer_get_modified (buffer))
2318 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2319 if (gtk_text_buffer_get_modified (buffer))
2321 if (gtk_text_buffer_get_modified (priv->text_buffer))
2328 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2330 ModestMsgEditWindowPrivate *priv = NULL;
2332 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2333 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2335 /* check if there's no recipient added */
2336 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2337 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2338 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2339 /* no recipient contents, then select contacts */
2340 modest_msg_edit_window_open_addressbook (window, NULL);
2344 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2346 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2348 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2351 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2358 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2359 ModestMsgEditWindow *window)
2361 modest_msg_edit_window_attach_file (window);
2365 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2367 ModestMsgEditWindow *window)
2369 ModestWindowPrivate *parent_priv;
2374 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2375 selection = gtk_clipboard_wait_for_text (clipboard);
2376 focused = gtk_window_get_focus (GTK_WINDOW (window));
2378 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2379 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2380 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2381 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2385 update_window_title (ModestMsgEditWindow *window)
2387 ModestMsgEditWindowPrivate *priv = NULL;
2388 const gchar *subject;
2390 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2391 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2392 if (subject == NULL || subject[0] == '\0')
2393 subject = _("mail_va_new_email");
2395 gtk_window_set_title (GTK_WINDOW (window), subject);
2400 subject_field_changed (GtkEditable *editable,
2401 ModestMsgEditWindow *window)
2403 update_window_title (window);