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_remove_attachments (ModestMsgEditWindow *window,
1490 ModestMsgEditWindowPrivate *priv;
1491 gboolean clean_list = FALSE;
1493 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1494 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1496 if (att_list == NULL) {
1497 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1501 if (att_list == NULL) {
1502 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1504 GtkWidget *confirmation_dialog = NULL;
1505 gboolean dialog_response;
1507 if (att_list->next == NULL) {
1508 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1509 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1510 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1513 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1515 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1516 gtk_widget_destroy (confirmation_dialog);
1517 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1519 for (node = att_list; node != NULL; node = g_list_next (node)) {
1520 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1521 const gchar *att_id;
1522 priv->attachments = g_list_remove (priv->attachments, mime_part);
1524 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1526 att_id = tny_mime_part_get_content_id (mime_part);
1528 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1530 g_object_unref (mime_part);
1535 g_list_free (att_list);
1539 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1542 ModestMsgEditWindowPrivate *priv;
1543 GdkColor *new_color;
1544 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1546 #ifdef MODEST_HILDON_VERSION_0
1547 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1550 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1552 #endif /*MODEST_HILDON_VERSION_0*/
1554 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1556 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1561 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1564 ModestMsgEditWindowPrivate *priv;
1565 gint new_size_index;
1566 ModestMsgEditWindow *window;
1569 window = MODEST_MSG_EDIT_WINDOW (userdata);
1570 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1571 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1573 if (gtk_check_menu_item_get_active (menu_item)) {
1575 WPTextBufferFormat format;
1577 label = gtk_bin_get_child (GTK_BIN (menu_item));
1579 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1580 memset (&format, 0, sizeof (format));
1581 format.cs.font_size = TRUE;
1582 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1583 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1585 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1586 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1587 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1589 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1590 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1591 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1597 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1600 ModestMsgEditWindowPrivate *priv;
1601 gint new_font_index;
1602 ModestMsgEditWindow *window;
1605 window = MODEST_MSG_EDIT_WINDOW (userdata);
1606 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1607 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1609 if (gtk_check_menu_item_get_active (menu_item)) {
1612 label = gtk_bin_get_child (GTK_BIN (menu_item));
1614 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1616 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1617 (gpointer) new_font_index))
1618 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1620 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1621 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1622 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1628 modest_msg_edit_window_set_zoom (ModestWindow *window,
1631 ModestMsgEditWindowPrivate *priv;
1633 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1635 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1636 priv->zoom_level = zoom;
1637 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1641 modest_msg_edit_window_get_zoom (ModestWindow *window)
1643 ModestMsgEditWindowPrivate *priv;
1645 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1647 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1648 return priv->zoom_level;
1652 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1654 ModestWindowPrivate *parent_priv;
1655 GtkRadioAction *zoom_radio_action;
1656 GSList *group, *node;
1658 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1659 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1660 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1662 group = gtk_radio_action_get_group (zoom_radio_action);
1664 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1665 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1669 for (node = group; node != NULL; node = g_slist_next (node)) {
1670 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1671 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1679 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1681 ModestWindowPrivate *parent_priv;
1682 GtkRadioAction *zoom_radio_action;
1683 GSList *group, *node;
1685 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1686 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1687 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1689 group = gtk_radio_action_get_group (zoom_radio_action);
1691 for (node = group; node != NULL; node = g_slist_next (node)) {
1692 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1693 if (node->next != NULL) {
1694 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1697 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1705 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1707 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1708 ModestWindowPrivate *parent_priv;
1709 ModestWindowMgr *mgr;
1710 gboolean is_fullscreen;
1711 GtkAction *fs_toggle_action;
1714 mgr = modest_runtime_get_window_mgr ();
1715 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1717 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1719 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1720 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1721 if (is_fullscreen != active)
1722 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1730 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1732 ModestWindowPrivate *parent_priv;
1733 GtkAction *fs_toggle_action;
1736 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1738 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1739 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1740 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1744 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1747 ModestMsgEditWindowPrivate *priv = NULL;
1748 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1750 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1752 gtk_widget_show (priv->cc_caption);
1754 gtk_widget_hide (priv->cc_caption);
1758 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1761 ModestMsgEditWindowPrivate *priv = NULL;
1762 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1764 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1766 gtk_widget_show (priv->bcc_caption);
1768 gtk_widget_hide (priv->bcc_caption);
1772 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1773 ModestRecptEditor *editor)
1775 ModestMsgEditWindowPrivate *priv;
1777 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1778 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1779 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1781 if (editor == NULL) {
1782 GtkWidget *view_focus;
1783 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1785 /* This code should be kept in sync with ModestRecptEditor. The
1786 textview inside the recpt editor is the one that really gets the
1787 focus. As it's inside a scrolled window, and this one inside the
1788 hbox recpt editor inherits from, we'll need to go up in the
1789 hierarchy to know if the text view is part of the recpt editor
1790 or if it's a different text entry */
1792 if (gtk_widget_get_parent (view_focus)) {
1793 GtkWidget *first_parent;
1795 first_parent = gtk_widget_get_parent (view_focus);
1796 if (gtk_widget_get_parent (first_parent) &&
1797 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1798 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1803 editor = MODEST_RECPT_EDITOR (priv->to_field);
1807 modest_address_book_select_addresses (editor);
1812 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1814 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1816 modest_msg_edit_window_open_addressbook (window, NULL);
1820 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1821 gboolean show_toolbar)
1823 ModestWindowPrivate *parent_priv;
1825 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1826 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1828 /* FIXME: we can not just use the code of
1829 modest_msg_edit_window_setup_toolbar because it has a
1830 mixture of both initialization and creation code. */
1833 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1835 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1839 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1840 TnyHeaderFlags priority_flags)
1842 ModestMsgEditWindowPrivate *priv;
1844 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1846 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1847 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1849 if (priv->priority_flags != priority_flags) {
1851 priv->priority_flags = priority_flags;
1853 switch (priority_flags) {
1854 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1855 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1856 gtk_widget_show (priv->priority_icon);
1858 case TNY_HEADER_FLAG_LOW_PRIORITY:
1859 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1860 gtk_widget_show (priv->priority_icon);
1863 gtk_widget_hide (priv->priority_icon);
1870 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1873 ModestMsgEditWindowPrivate *priv;
1874 gint current_format;
1876 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1878 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1880 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1881 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1883 if (current_format != file_format) {
1884 switch (file_format) {
1885 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1886 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1888 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1892 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1893 response = gtk_dialog_run (GTK_DIALOG (dialog));
1894 gtk_widget_destroy (dialog);
1895 if (response == GTK_RESPONSE_OK)
1896 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1900 update_dimmed (window);
1905 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1908 ModestMsgEditWindowPrivate *priv;
1909 WPTextBufferFormat oldfmt, fmt;
1910 gint old_position = 0;
1914 GdkColor *color = NULL;
1915 gboolean bold, bold_set, italic, italic_set;
1916 gboolean underline, underline_set;
1917 gboolean strikethrough, strikethrough_set;
1918 gboolean position_set;
1919 gboolean font_size_set, font_set, color_set;
1922 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1923 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1925 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
1927 /* First we get the currently selected font information */
1928 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
1929 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
1931 switch (oldfmt.text_position) {
1932 case TEXT_POSITION_NORMAL:
1935 case TEXT_POSITION_SUPERSCRIPT:
1943 g_object_set (G_OBJECT (dialog),
1944 "bold", oldfmt.bold != FALSE,
1945 "bold-set", !oldfmt.cs.bold,
1946 "underline", oldfmt.underline != FALSE,
1947 "underline-set", !oldfmt.cs.underline,
1948 "italic", oldfmt.italic != FALSE,
1949 "italic-set", !oldfmt.cs.italic,
1950 "strikethrough", oldfmt.strikethrough != FALSE,
1951 "strikethrough-set", !oldfmt.cs.strikethrough,
1952 "color", &oldfmt.color,
1953 "color-set", !oldfmt.cs.color,
1954 "size", wp_font_size[oldfmt.font_size],
1955 "size-set", !oldfmt.cs.font_size,
1956 "position", old_position,
1957 "position-set", !oldfmt.cs.text_position,
1958 "family", wp_get_font_name (oldfmt.font),
1959 "family-set", !oldfmt.cs.font,
1962 gtk_widget_show_all (dialog);
1963 response = gtk_dialog_run (GTK_DIALOG (dialog));
1964 if (response == GTK_RESPONSE_OK) {
1966 g_object_get( dialog,
1968 "bold-set", &bold_set,
1969 "underline", &underline,
1970 "underline-set", &underline_set,
1972 "italic-set", &italic_set,
1973 "strikethrough", &strikethrough,
1974 "strikethrough-set", &strikethrough_set,
1976 "color-set", &color_set,
1978 "size-set", &font_size_set,
1979 "family", &font_name,
1980 "family-set", &font_set,
1981 "position", &position,
1982 "position-set", &position_set,
1987 if (response == GTK_RESPONSE_OK) {
1988 memset(&fmt, 0, sizeof(fmt));
1994 fmt.italic = italic;
1995 fmt.cs.italic = TRUE;
1997 if (underline_set) {
1998 fmt.underline = underline;
1999 fmt.cs.underline = TRUE;
2001 if (strikethrough_set) {
2002 fmt.strikethrough = strikethrough;
2003 fmt.cs.strikethrough = TRUE;
2008 ? TEXT_POSITION_NORMAL
2009 : ( ( position == 1 )
2010 ? TEXT_POSITION_SUPERSCRIPT
2011 : TEXT_POSITION_SUBSCRIPT );
2012 fmt.cs.text_position = TRUE;
2016 fmt.cs.color = TRUE;
2019 fmt.font = wp_get_font_index(font_name,
2024 if (font_size_set) {
2025 fmt.font_size = wp_get_font_size_index(
2026 font_size, DEFAULT_FONT_SIZE);
2027 fmt.cs.font_size = TRUE;
2029 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2031 gtk_widget_destroy (dialog);
2033 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2037 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2039 ModestMsgEditWindowPrivate *priv;
2041 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2042 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2044 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2046 update_dimmed (window);
2051 update_dimmed (ModestMsgEditWindow *window)
2053 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2054 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2058 gboolean editor_focused;
2060 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2061 editor_focused = gtk_widget_is_focus (priv->msg_body);
2063 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2064 gtk_action_set_sensitive (action, rich_text && editor_focused);
2065 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2066 gtk_action_set_sensitive (action, rich_text && editor_focused);
2067 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2068 gtk_action_set_sensitive (action, rich_text && editor_focused);
2069 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2070 gtk_action_set_sensitive (action, rich_text && editor_focused);
2071 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2072 gtk_action_set_sensitive (action, rich_text && editor_focused);
2073 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2074 gtk_action_set_sensitive (action, rich_text && editor_focused);
2075 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2076 gtk_action_set_sensitive (action, rich_text && editor_focused);
2077 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2078 gtk_action_set_sensitive (action, rich_text && editor_focused);
2079 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2080 gtk_action_set_sensitive (action, rich_text && editor_focused);
2081 widget = priv->font_color_button;
2082 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2083 widget = priv->font_size_toolitem;
2084 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2085 widget = priv->font_face_toolitem;
2086 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2090 setup_insensitive_handlers (ModestMsgEditWindow *window)
2092 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2093 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2096 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2097 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2098 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2099 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2101 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2102 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2103 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2104 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2105 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2106 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2107 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2108 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2109 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2110 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2111 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2112 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2113 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2114 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2115 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2116 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2117 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2118 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2119 widget = priv->font_color_button;
2120 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2121 widget = priv->font_size_toolitem;
2122 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2123 widget = priv->font_face_toolitem;
2124 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2129 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2131 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2134 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2135 gtk_action_set_sensitive (action, can_undo);
2139 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2142 GtkTextIter match_start, match_end;
2144 if (image_id == NULL)
2147 gtk_text_buffer_get_start_iter (buffer, &iter);
2149 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2150 GSList *tags = gtk_text_iter_get_tags (&match_start);
2152 for (node = tags; node != NULL; node = g_slist_next (node)) {
2153 GtkTextTag *tag = (GtkTextTag *) node->data;
2154 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2155 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2156 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2158 offset = gtk_text_iter_get_offset (&match_start);
2159 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2160 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2164 gtk_text_iter_forward_char (&iter);
2169 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2171 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2172 GtkTextIter real_start, real_end;
2173 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2175 if (gtk_text_iter_compare (start, end) > 0) {
2179 real_start = *start;
2183 GSList *tags = gtk_text_iter_get_tags (&real_start);
2185 for (node = tags; node != NULL; node = g_slist_next (node)) {
2186 GtkTextTag *tag = (GtkTextTag *) node->data;
2187 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2188 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2190 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2192 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2195 } while (gtk_text_iter_forward_char (&real_start)&&
2196 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2200 msg_body_focus (GtkWidget *focus,
2201 GdkEventFocus *event,
2205 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2210 to_field_changed (GtkTextBuffer *buffer,
2211 ModestMsgEditWindow *editor)
2213 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2216 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2217 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2218 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2219 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2223 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2225 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2229 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2231 gboolean rich_text, editor_focused;
2233 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2234 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2235 editor_focused = gtk_widget_is_focus (priv->msg_body);
2238 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2239 else if (!editor_focused)
2240 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2244 reset_modified (ModestMsgEditWindow *editor)
2246 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2247 GtkTextBuffer *buffer;
2249 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2250 gtk_text_buffer_set_modified (buffer, FALSE);
2251 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2252 gtk_text_buffer_set_modified (buffer, FALSE);
2253 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2254 gtk_text_buffer_set_modified (buffer, FALSE);
2255 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2259 is_modified (ModestMsgEditWindow *editor)
2261 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2262 GtkTextBuffer *buffer;
2264 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2265 if (gtk_text_buffer_get_modified (buffer))
2267 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2268 if (gtk_text_buffer_get_modified (buffer))
2270 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2271 if (gtk_text_buffer_get_modified (buffer))
2273 if (gtk_text_buffer_get_modified (priv->text_buffer))
2280 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2282 ModestMsgEditWindowPrivate *priv = NULL;
2284 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2285 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2287 /* check if there's no recipient added */
2288 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2289 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2290 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2291 /* no recipient contents, then select contacts */
2292 modest_msg_edit_window_open_addressbook (window, NULL);
2296 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2298 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2300 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2303 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2310 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2311 ModestMsgEditWindow *window)
2313 modest_msg_edit_window_attach_file (window);
2317 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2319 ModestMsgEditWindow *window)
2321 ModestWindowPrivate *parent_priv;
2326 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2327 selection = gtk_clipboard_wait_for_text (clipboard);
2328 focused = gtk_window_get_focus (GTK_WINDOW (window));
2330 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2331 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2332 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2333 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2337 update_window_title (ModestMsgEditWindow *window)
2339 ModestMsgEditWindowPrivate *priv = NULL;
2340 const gchar *subject;
2342 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2343 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2344 if (subject == NULL || subject[0] == '\0')
2345 subject = _("mail_va_new_email");
2347 gtk_window_set_title (GTK_WINDOW (window), subject);
2352 subject_field_changed (GtkEditable *editable,
2353 ModestMsgEditWindow *window)
2355 update_window_title (window);