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>
40 #include <modest-account-mgr.h>
41 #include <modest-account-mgr-helpers.h>
43 #include <widgets/modest-msg-edit-window.h>
44 #include <widgets/modest-combo-box.h>
45 #include <widgets/modest-recpt-editor.h>
46 #include <widgets/modest-attachments-view.h>
48 #include <modest-runtime.h>
50 #include "modest-platform.h"
51 #include "modest-icon-names.h"
52 #include "modest-widget-memory.h"
53 #include "modest-window-priv.h"
54 #include "modest-mail-operation.h"
55 #include "modest-tny-platform-factory.h"
56 #include "modest-tny-msg.h"
57 #include "modest-address-book.h"
58 #include "modest-text-utils.h"
59 #include <tny-simple-list.h>
60 #include <wptextview.h>
61 #include <wptextbuffer.h>
62 #include "modest-scroll-area.h"
64 #include "modest-hildon-includes.h"
65 #include "widgets/modest-msg-edit-window-ui.h"
66 #include <libgnomevfs/gnome-vfs-mime.h>
69 #define DEFAULT_FONT_SIZE 3
70 #define DEFAULT_FONT 2
71 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
72 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
73 #define DEFAULT_MAIN_VBOX_SPACING 6
74 #define SUBJECT_MAX_LENGTH 1000
76 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
77 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
78 static void modest_msg_edit_window_finalize (GObject *obj);
80 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
81 static void to_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
82 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
83 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
84 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
85 static void reset_modified (ModestMsgEditWindow *editor);
86 static gboolean is_modified (ModestMsgEditWindow *editor);
88 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
89 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
90 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
91 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
92 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
93 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
95 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
97 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
99 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
100 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
101 GdkEventWindowState *event,
103 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
104 ModestRecptEditor *editor);
105 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
106 ModestMsgEditWindow *window);
108 /* ModestWindow methods implementation */
109 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
110 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
111 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
112 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
113 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
114 gboolean show_toolbar);
115 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
117 ModestMsgEditWindow *window);
118 static void update_window_title (ModestMsgEditWindow *window);
119 static void update_dimmed (ModestMsgEditWindow *window);
122 /* list my signals */
129 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
130 struct _ModestMsgEditWindowPrivate {
132 GtkWidget *header_box;
134 ModestPairList *from_field_protos;
135 GtkWidget *from_field;
139 GtkWidget *bcc_field;
140 GtkWidget *subject_field;
141 GtkWidget *attachments_view;
142 GtkWidget *priority_icon;
143 GtkWidget *add_attachment_button;
145 GtkWidget *cc_caption;
146 GtkWidget *bcc_caption;
147 GtkWidget *attachments_caption;
149 GtkTextBuffer *text_buffer;
151 GtkWidget *font_size_toolitem;
152 GtkWidget *font_face_toolitem;
153 GtkWidget *font_color_button;
154 GSList *font_items_group;
155 GtkWidget *font_tool_button_label;
156 GSList *size_items_group;
157 GtkWidget *size_tool_button_label;
164 TnyHeaderFlags priority_flags;
168 gulong clipboard_change_handler_id;
173 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
174 MODEST_TYPE_MSG_EDIT_WINDOW, \
175 ModestMsgEditWindowPrivate))
177 static GtkWindowClass *parent_class = NULL;
179 /* uncomment the following if you have defined any signals */
180 /* static guint signals[LAST_SIGNAL] = {0}; */
183 modest_msg_edit_window_get_type (void)
185 static GType my_type = 0;
187 static const GTypeInfo my_info = {
188 sizeof(ModestMsgEditWindowClass),
189 NULL, /* base init */
190 NULL, /* base finalize */
191 (GClassInitFunc) modest_msg_edit_window_class_init,
192 NULL, /* class finalize */
193 NULL, /* class data */
194 sizeof(ModestMsgEditWindow),
196 (GInstanceInitFunc) modest_msg_edit_window_init,
199 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
200 "ModestMsgEditWindow",
203 wp_text_buffer_library_init ();
209 save_state (ModestWindow *self)
211 modest_widget_memory_save (modest_runtime_get_conf(),
212 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
217 restore_settings (ModestMsgEditWindow *self)
219 modest_widget_memory_restore (modest_runtime_get_conf(),
220 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
225 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
227 GObjectClass *gobject_class;
228 ModestWindowClass *modest_window_class;
229 gobject_class = (GObjectClass*) klass;
230 modest_window_class = (ModestWindowClass*) klass;
232 parent_class = g_type_class_peek_parent (klass);
233 gobject_class->finalize = modest_msg_edit_window_finalize;
235 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
236 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
237 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
238 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
239 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
241 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
243 modest_window_class->save_state_func = save_state;
247 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
249 ModestMsgEditWindowPrivate *priv;
250 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
252 priv->msg_body = NULL;
253 priv->from_field = NULL;
254 priv->to_field = NULL;
255 priv->cc_field = NULL;
256 priv->bcc_field = NULL;
257 priv->subject_field = NULL;
258 priv->attachments = NULL;
260 priv->zoom_level = 1.0;
262 priv->cc_caption = NULL;
263 priv->bcc_caption = NULL;
265 priv->priority_flags = 0;
267 priv->draft_msg = NULL;
268 priv->clipboard_change_handler_id = 0;
272 /* FIXME: this is a dup from the one in gtk/ */
275 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
277 static ModestPairList*
278 get_transports (void)
280 GSList *transports = NULL;
282 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
283 GSList *accounts = modest_account_mgr_account_names (account_mgr,
284 TRUE /* only enabled accounts. */);
286 GSList *cursor = accounts;
288 const gchar *account_name = cursor->data;
289 gchar *from_string = NULL;
291 from_string = modest_account_mgr_get_from_string (account_mgr,
295 if (from_string && account_name) {
296 gchar *name = g_strdup (account_name);
297 ModestPair *pair = modest_pair_new ((gpointer) name,
298 (gpointer) from_string , TRUE);
299 transports = g_slist_prepend (transports, pair);
302 cursor = cursor->next;
304 g_slist_free (accounts);
310 init_window (ModestMsgEditWindow *obj)
312 GtkWidget *from_caption, *to_caption, *subject_caption;
313 GtkWidget *main_vbox;
314 ModestMsgEditWindowPrivate *priv;
316 GtkSizeGroup *size_group;
318 GtkWidget *scroll_area;
319 GtkWidget *subject_box;
320 GtkWidget *attachment_icon;
322 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
324 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
326 /* Note: This ModestPairList* must exist for as long as the combo
327 * that uses it, because the ModestComboBox uses the ID opaquely,
328 * so it can't know how to manage its memory. */
329 priv->from_field_protos = get_transports ();
331 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
333 priv->to_field = modest_recpt_editor_new ();
334 priv->cc_field = modest_recpt_editor_new ();
335 priv->bcc_field = modest_recpt_editor_new ();
336 subject_box = gtk_hbox_new (FALSE, 0);
337 priv->priority_icon = gtk_image_new ();
338 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
339 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
340 g_object_set (G_OBJECT (priv->subject_field), "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
341 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
342 priv->add_attachment_button = gtk_button_new ();
343 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
344 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
345 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
346 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
347 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
348 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
349 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
350 priv->attachments_view = modest_attachments_view_new (NULL);
352 priv->header_box = gtk_vbox_new (FALSE, 0);
354 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
355 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
356 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
357 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
358 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
359 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
360 g_object_unref (size_group);
362 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
363 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
364 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
365 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
366 gtk_size_group_add_widget (size_group, priv->subject_field);
367 gtk_size_group_add_widget (size_group, priv->attachments_view);
368 g_object_unref (size_group);
370 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
371 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
372 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
373 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
374 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
375 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
376 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
379 priv->msg_body = wp_text_view_new ();
380 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
381 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
382 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
383 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
384 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
385 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
387 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
388 G_CALLBACK (text_buffer_refresh_attributes), obj);
389 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
390 G_CALLBACK (text_buffer_delete_range), obj);
391 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
392 G_CALLBACK (text_buffer_can_undo), obj);
393 g_signal_connect (G_OBJECT (obj), "window-state-event",
394 G_CALLBACK (modest_msg_edit_window_window_state_event),
396 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
397 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
398 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
399 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
400 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
401 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
403 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
404 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
406 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
407 G_CALLBACK (msg_body_focus), obj);
408 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
409 G_CALLBACK (msg_body_focus), obj);
410 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
411 "changed", G_CALLBACK (to_field_changed), obj);
412 to_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
413 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
415 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
416 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
417 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
419 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
421 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
422 frame = gtk_frame_new (NULL);
423 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
425 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
426 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
427 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
429 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL))
430 gtk_widget_hide (priv->cc_field);
431 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL))
432 gtk_widget_hide (priv->bcc_field);
434 gtk_container_add (GTK_CONTAINER(obj), priv->scroll);
435 scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
436 gtk_container_add (GTK_CONTAINER (frame), scroll_area);
437 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
438 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
440 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
441 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
447 modest_msg_edit_window_finalize (GObject *obj)
449 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
452 if (priv->clipboard_change_handler_id > 0) {
453 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
454 priv->clipboard_change_handler_id = 0;
457 /* This had to stay alive for as long as the combobox that used it: */
458 modest_pair_list_free (priv->from_field_protos);
460 G_OBJECT_CLASS(parent_class)->finalize (obj);
464 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
466 GtkWidget *close_dialog;
467 ModestMsgEditWindowPrivate *priv;
470 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
471 modest_window_save_state (MODEST_WINDOW (self));
472 if (is_modified (self)) {
473 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
474 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
475 gtk_widget_destroy (close_dialog);
477 if (response != GTK_RESPONSE_CANCEL) {
478 modest_ui_actions_on_save_to_drafts (NULL, self);
481 /* /\* remove old message from drafts *\/ */
482 /* if (priv->draft_msg) { */
483 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
484 /* TnyAccount *account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(), */
486 /* TNY_ACCOUNT_TYPE_STORE); */
487 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
488 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
489 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
490 /* tny_folder_remove_msg (folder, header, NULL); */
491 /* g_object_unref (folder); */
492 /* g_object_unref (header); */
493 /* g_object_unref (priv->draft_msg); */
494 /* priv->draft_msg = NULL; */
496 gtk_widget_destroy (GTK_WIDGET (self));
502 menubar_to_menu (GtkUIManager *ui_manager)
504 GtkWidget *main_menu;
508 /* Create new main menu */
509 main_menu = gtk_menu_new();
511 /* Get the menubar from the UI manager */
512 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
514 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
518 menu = GTK_WIDGET (iter->data);
519 gtk_widget_reparent(menu, main_menu);
521 iter = g_list_next (iter);
528 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
531 const gchar *to, *cc, *bcc, *subject;
533 ModestMsgEditWindowPrivate *priv;
536 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
537 g_return_if_fail (TNY_IS_MSG (msg));
539 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
541 header = tny_msg_get_header (msg);
542 to = tny_header_get_to (header);
543 cc = tny_header_get_cc (header);
544 bcc = tny_header_get_bcc (header);
545 subject = tny_header_get_subject (header);
548 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
550 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
552 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
554 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
556 update_window_title (self);
558 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
559 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
560 body = modest_tny_msg_get_body (msg, TRUE);
562 if ((body == NULL)||(body[0] == '\0')) {
564 body = modest_text_utils_convert_to_html ("");
566 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
567 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
570 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
573 /* Get the default format required from configuration */
574 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
575 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
578 /* Set the default focus depending on having already a To: field or not */
579 if ((!to)||(*to == '\0')) {
580 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
582 gtk_widget_grab_focus (priv->msg_body);
585 /* TODO: lower priority, select in the From: combo to the
586 value that comes from msg <- not sure, should it be
589 /* Add attachments to the view */
590 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
591 if (priv->attachments == NULL)
592 gtk_widget_hide_all (priv->attachments_caption);
594 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
595 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
597 reset_modified (self);
599 update_dimmed (self);
600 text_buffer_can_undo (priv->text_buffer, FALSE, self);
602 priv->draft_msg = msg;
606 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
609 GList *item_children, *node;
610 GtkWidget *bin_child;
612 bin_child = gtk_bin_get_child (GTK_BIN(item));
614 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
616 for (node = item_children; node != NULL; node = g_list_next (node)) {
617 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
618 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
621 g_list_free (item_children);
625 menu_tool_button_dont_expand (GtkMenuToolButton *item)
628 GList *item_children, *node;
630 box = gtk_bin_get_child (GTK_BIN (item));
631 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
632 item_children = gtk_container_get_children (GTK_CONTAINER (box));
634 for (node = item_children; node != NULL; node = g_list_next (node)) {
635 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
636 if (GTK_IS_TOGGLE_BUTTON (node->data))
637 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
638 else if (GTK_IS_BUTTON (node->data))
639 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
641 g_list_free (item_children);
646 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
648 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
649 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
650 GtkWidget *placeholder;
651 GtkWidget *tool_item;
656 GtkWidget *sizes_menu;
657 GtkWidget *fonts_menu;
658 GSList *radio_group = NULL;
663 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
664 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
666 /* should we hide the toolbar? */
667 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
668 gtk_widget_hide (parent_priv->toolbar);
670 /* Font color placeholder */
671 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
672 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
675 tool_item = GTK_WIDGET (gtk_tool_item_new ());
676 priv->font_color_button = hildon_color_button_new ();
677 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
678 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
679 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
680 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
681 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
682 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
683 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
685 /* Font size and face placeholder */
686 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
687 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
689 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
690 priv->size_tool_button_label = gtk_label_new (NULL);
691 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
692 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
693 size_text,"</span>", NULL);
694 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
696 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
697 sizes_menu = gtk_menu_new ();
698 priv->size_items_group = NULL;
700 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
701 GtkWidget *size_menu_item;
703 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
704 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
705 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
706 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
707 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
708 gtk_widget_show (size_menu_item);
710 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
714 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
715 GtkWidget *item = (GtkWidget *) node->data;
716 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
720 priv->size_items_group = g_slist_reverse (priv->size_items_group);
721 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
722 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
723 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
724 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
725 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
726 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
727 priv->font_size_toolitem = tool_item;
730 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
731 priv->font_tool_button_label = gtk_label_new (NULL);
732 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
733 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
735 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
736 fonts_menu = gtk_menu_new ();
737 priv->font_items_group = NULL;
739 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
740 GtkWidget *font_menu_item;
741 GtkWidget *child_label;
743 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
744 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
745 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
746 wp_get_font_name (font_index), "</span>", NULL);
747 gtk_label_set_markup (GTK_LABEL (child_label), markup);
750 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
751 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
752 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
753 gtk_widget_show (font_menu_item);
755 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
758 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
759 GtkWidget *item = (GtkWidget *) node->data;
760 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
763 priv->font_items_group = g_slist_reverse (priv->font_items_group);
764 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
765 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
766 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
767 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
768 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
769 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
770 priv->font_face_toolitem = tool_item;
772 /* Set expand and homogeneous for remaining items */
773 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
774 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
775 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
776 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
777 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
778 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
779 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
780 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
781 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
789 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
792 ModestWindowPrivate *parent_priv;
793 ModestMsgEditWindowPrivate *priv;
794 GtkActionGroup *action_group;
795 GError *error = NULL;
796 GdkPixbuf *window_icon = NULL;
799 gboolean prefer_formatted;
802 g_return_val_if_fail (msg, NULL);
804 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
806 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
807 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
809 parent_priv->ui_manager = gtk_ui_manager_new();
810 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
811 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
813 /* Add common actions */
814 gtk_action_group_add_actions (action_group,
815 modest_msg_edit_action_entries,
816 G_N_ELEMENTS (modest_msg_edit_action_entries),
818 gtk_action_group_add_toggle_actions (action_group,
819 modest_msg_edit_toggle_action_entries,
820 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
822 gtk_action_group_add_radio_actions (action_group,
823 modest_msg_edit_alignment_radio_action_entries,
824 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
826 G_CALLBACK (modest_ui_actions_on_change_justify),
828 gtk_action_group_add_radio_actions (action_group,
829 modest_msg_edit_zoom_action_entries,
830 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
832 G_CALLBACK (modest_ui_actions_on_change_zoom),
834 gtk_action_group_add_radio_actions (action_group,
835 modest_msg_edit_priority_action_entries,
836 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
838 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
840 gtk_action_group_add_radio_actions (action_group,
841 modest_msg_edit_file_format_action_entries,
842 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
843 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
844 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
846 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
847 g_object_unref (action_group);
849 /* Load the UI definition */
850 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml", &error);
852 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
853 g_clear_error (&error);
856 /* Add accelerators */
857 gtk_window_add_accel_group (GTK_WINDOW (obj),
858 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
861 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
862 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
865 init_window (MODEST_MSG_EDIT_WINDOW(obj));
867 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
869 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
871 g_signal_connect (G_OBJECT(obj), "delete-event",
872 G_CALLBACK(on_delete_event), obj);
874 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
876 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
878 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
880 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
882 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
884 /* Set window icon */
885 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
886 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
888 /* Dim at start clipboard actions */
889 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
890 gtk_action_set_sensitive (action, FALSE);
891 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
892 gtk_action_set_sensitive (action, FALSE);
894 /* Setup the file format */
895 conf = modest_runtime_get_conf ();
896 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
898 g_clear_error (&error);
899 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
901 file_format = (prefer_formatted) ?
902 MODEST_FILE_FORMAT_FORMATTED_TEXT :
903 MODEST_FILE_FORMAT_PLAIN_TEXT;
904 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
906 return (ModestWindow*) obj;
910 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
912 GString **string_buffer = (GString **) user_data;
914 *string_buffer = g_string_append (*string_buffer, buffer);
920 * @result: A new string which should be freed with g_free().
923 get_formatted_data (ModestMsgEditWindow *edit_window)
925 ModestMsgEditWindowPrivate *priv;
926 GString *string_buffer = g_string_new ("");
928 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
930 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
932 return g_string_free (string_buffer, FALSE);
937 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
940 const gchar *account_name;
941 ModestMsgEditWindowPrivate *priv;
943 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
945 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
947 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
948 g_return_val_if_fail (account_name, NULL);
951 /* don't free these (except from) */
952 data = g_slice_new0 (MsgData);
953 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
955 data->account_name = g_strdup (account_name);
956 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
957 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
958 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
959 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
960 if (priv->draft_msg) {
961 data->draft_msg = g_object_ref (priv->draft_msg);
963 data->draft_msg = NULL;
966 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
968 gtk_text_buffer_get_bounds (buf, &b, &e);
969 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
971 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
972 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
974 data->html_body = NULL;
976 data->attachments = priv->attachments; /* TODO: copy and free ? */
977 data->priority_flags = priv->priority_flags;
982 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
984 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
987 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
995 g_free (data->subject);
996 g_free (data->plain_body);
997 g_free (data->html_body);
998 if (data->draft_msg != NULL) {
999 g_object_unref (data->draft_msg);
1000 data->draft_msg = NULL;
1002 g_free (data->account_name);
1004 /* TODO: Free data->attachments? */
1006 g_slice_free (MsgData, data);
1010 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1013 ModestMsgEditWindowPrivate *priv = NULL;
1014 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1016 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1018 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1020 return MODEST_MSG_EDIT_FORMAT_HTML;
1022 return MODEST_MSG_EDIT_FORMAT_TEXT;
1026 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1027 ModestMsgEditFormat format)
1029 ModestMsgEditWindowPrivate *priv;
1031 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1032 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1035 case MODEST_MSG_EDIT_FORMAT_HTML:
1036 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1038 case MODEST_MSG_EDIT_FORMAT_TEXT:
1039 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1042 g_return_if_reached ();
1046 ModestMsgEditFormatState *
1047 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1049 ModestMsgEditFormatState *format_state = NULL;
1050 ModestMsgEditWindowPrivate *priv;
1051 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1053 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1054 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1056 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1058 format_state = g_new0 (ModestMsgEditFormatState, 1);
1059 format_state->bold = buffer_format->bold&0x1;
1060 format_state->italics = buffer_format->italic&0x1;
1061 format_state->bullet = buffer_format->bullet&0x1;
1062 format_state->color = buffer_format->color;
1063 format_state->font_size = buffer_format->font_size;
1064 format_state->font_family = wp_get_font_name (buffer_format->font);
1065 format_state->justification = buffer_format->justification;
1066 g_free (buffer_format);
1068 return format_state;
1073 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1074 const ModestMsgEditFormatState *format_state)
1076 ModestMsgEditWindowPrivate *priv;
1077 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1078 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1079 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1080 g_return_if_fail (format_state != NULL);
1082 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1083 gtk_widget_grab_focus (priv->msg_body);
1084 buffer_format->bold = (format_state->bold != FALSE);
1085 buffer_format->italic = (format_state->italics != FALSE);
1086 buffer_format->color = format_state->color;
1087 buffer_format->font_size = format_state->font_size;
1088 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1089 buffer_format->justification = format_state->justification;
1090 buffer_format->bullet = format_state->bullet;
1092 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1094 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1095 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1096 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1097 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1098 buffer_format->cs.font = (buffer_format->font != current_format->font);
1099 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1100 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1102 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1103 if (buffer_format->cs.bold) {
1104 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1106 if (buffer_format->cs.italic) {
1107 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1109 if (buffer_format->cs.color) {
1110 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1112 if (buffer_format->cs.font_size) {
1113 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1115 if (buffer_format->cs.justification) {
1116 switch (buffer_format->justification) {
1117 case GTK_JUSTIFY_LEFT:
1118 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1120 case GTK_JUSTIFY_CENTER:
1121 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1123 case GTK_JUSTIFY_RIGHT:
1124 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1131 if (buffer_format->cs.font) {
1132 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1134 if (buffer_format->cs.bullet) {
1135 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
1137 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1138 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1140 g_free (current_format);
1145 toggle_action_set_active_block_notify (GtkToggleAction *action,
1148 GSList *proxies = NULL;
1150 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1151 proxies != NULL; proxies = g_slist_next (proxies)) {
1152 GtkWidget *widget = (GtkWidget *) proxies->data;
1153 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1156 gtk_toggle_action_set_active (action, value);
1158 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1159 proxies != NULL; proxies = g_slist_next (proxies)) {
1160 GtkWidget *widget = (GtkWidget *) proxies->data;
1161 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1166 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1168 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1170 ModestWindowPrivate *parent_priv;
1171 ModestMsgEditWindowPrivate *priv;
1172 GtkWidget *new_size_menuitem;
1173 GtkWidget *new_font_menuitem;
1175 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1176 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1178 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1179 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1180 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1181 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1183 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1184 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1185 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1188 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1190 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1191 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1193 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1194 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1196 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1197 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1199 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1200 G_CALLBACK (modest_msg_edit_window_color_button_change),
1202 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1203 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1204 G_CALLBACK (modest_msg_edit_window_color_button_change),
1207 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1208 buffer_format->font_size))->data);
1209 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1213 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1214 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1215 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1217 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1218 G_CALLBACK (modest_msg_edit_window_size_change),
1220 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1221 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1222 G_CALLBACK (modest_msg_edit_window_size_change),
1226 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1227 buffer_format->font))->data);
1228 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1232 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1233 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1234 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1236 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1237 G_CALLBACK (modest_msg_edit_window_font_change),
1239 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1240 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1241 G_CALLBACK (modest_msg_edit_window_font_change),
1245 g_free (buffer_format);
1251 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1254 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1255 ModestMsgEditWindowPrivate *priv;
1256 GtkWidget *dialog = NULL;
1258 const GdkColor *new_color = NULL;
1260 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1261 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1263 #ifdef MODEST_HILDON_VERSION_0
1264 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1265 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1267 dialog = hildon_color_chooser_new ();
1268 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1269 #endif /*MODEST_HILDON_VERSION_0*/
1270 g_free (buffer_format);
1272 response = gtk_dialog_run (GTK_DIALOG (dialog));
1274 case GTK_RESPONSE_OK: {
1275 #ifdef MODEST_HILDON_VERSION_0
1276 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1279 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1281 #endif /*MODEST_HILDON_VERSION_0*/
1288 gtk_widget_destroy (dialog);
1290 if (new_color != NULL)
1291 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1296 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1299 ModestMsgEditWindowPrivate *priv;
1300 GtkWidget *dialog = NULL;
1302 GdkColor *old_color = NULL;
1303 const GdkColor *new_color = NULL;
1305 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1306 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1308 #ifdef MODEST_HILDON_VERSION_0
1309 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1310 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1312 dialog = hildon_color_chooser_new ();
1313 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1314 #endif /*MODEST_HILDON_VERSION_9*/
1316 response = gtk_dialog_run (GTK_DIALOG (dialog));
1318 case GTK_RESPONSE_OK: {
1319 #ifdef MODEST_HILDON_VERSION_0
1320 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1323 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1325 #endif /*MODEST_HILDON_VERSION_0*/
1331 gtk_widget_destroy (dialog);
1333 if (new_color != NULL)
1334 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1339 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1342 ModestMsgEditWindowPrivate *priv;
1343 GtkWidget *dialog = NULL;
1345 gchar *filename = NULL;
1347 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1349 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1351 response = gtk_dialog_run (GTK_DIALOG (dialog));
1353 case GTK_RESPONSE_OK:
1354 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1359 gtk_widget_destroy (dialog);
1362 GdkPixbuf *pixbuf = NULL;
1363 GtkTextIter position;
1364 GtkTextMark *insert_mark;
1366 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1369 GdkPixbufFormat *pixbuf_format;
1371 image_file_id = g_open (filename, O_RDONLY, 0);
1372 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1373 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1374 TnyMimePart *image_part;
1375 TnyStream *image_stream;
1381 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1382 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1383 mime_type = mime_types[0];
1385 mime_type = "image/unknown";
1387 image_part = tny_platform_factory_new_mime_part
1388 (modest_runtime_get_platform_factory ());
1389 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1391 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1392 g_strfreev (mime_types);
1394 content_id = g_strdup_printf ("%d", priv->last_cid);
1395 tny_mime_part_set_content_id (image_part, content_id);
1396 g_free (content_id);
1399 basename = g_path_get_basename (filename);
1400 tny_mime_part_set_filename (image_part, basename);
1403 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1404 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1405 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1406 priv->attachments = g_list_prepend (priv->attachments, image_part);
1407 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1409 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1410 gtk_widget_show_all (priv->attachments_caption);
1411 } else if (image_file_id == -1) {
1412 close (image_file_id);
1421 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1424 ModestMsgEditWindowPrivate *priv;
1425 GtkWidget *dialog = NULL;
1427 gchar *filename = NULL;
1429 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1431 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1433 response = gtk_dialog_run (GTK_DIALOG (dialog));
1435 case GTK_RESPONSE_OK:
1436 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1441 gtk_widget_destroy (dialog);
1446 file_id = g_open (filename, O_RDONLY, 0);
1447 if (file_id != -1) {
1448 TnyMimePart *mime_part;
1450 const gchar *mime_type;
1454 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1455 mime_part = tny_platform_factory_new_mime_part
1456 (modest_runtime_get_platform_factory ());
1457 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1459 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1461 content_id = g_strdup_printf ("%d", priv->last_cid);
1462 tny_mime_part_set_content_id (mime_part, content_id);
1463 g_free (content_id);
1466 basename = g_path_get_basename (filename);
1467 tny_mime_part_set_filename (mime_part, basename);
1470 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1471 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1473 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1474 gtk_widget_show_all (priv->attachments_caption);
1475 } else if (file_id == -1) {
1482 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1485 ModestMsgEditWindowPrivate *priv;
1486 gboolean clean_list = FALSE;
1488 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1489 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1491 if (att_list == NULL) {
1492 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1496 if (att_list == NULL) {
1497 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1499 GtkWidget *confirmation_dialog = NULL;
1500 gboolean dialog_response;
1502 if (att_list->next == NULL) {
1503 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1504 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1505 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1508 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1510 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1511 gtk_widget_destroy (confirmation_dialog);
1512 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1514 for (node = att_list; node != NULL; node = g_list_next (node)) {
1515 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1516 const gchar *att_id;
1517 priv->attachments = g_list_remove (priv->attachments, mime_part);
1519 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1521 att_id = tny_mime_part_get_content_id (mime_part);
1523 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1525 g_object_unref (mime_part);
1530 g_list_free (att_list);
1534 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1537 ModestMsgEditWindowPrivate *priv;
1538 GdkColor *new_color;
1539 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1541 #ifdef MODEST_HILDON_VERSION_0
1542 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1545 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1547 #endif /*MODEST_HILDON_VERSION_0*/
1549 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1551 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1556 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1559 ModestMsgEditWindowPrivate *priv;
1560 gint new_size_index;
1561 ModestMsgEditWindow *window;
1564 window = MODEST_MSG_EDIT_WINDOW (userdata);
1565 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1566 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1568 if (gtk_check_menu_item_get_active (menu_item)) {
1570 WPTextBufferFormat format;
1572 label = gtk_bin_get_child (GTK_BIN (menu_item));
1574 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1575 memset (&format, 0, sizeof (format));
1576 format.cs.font_size = TRUE;
1577 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1578 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1580 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1581 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1582 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1584 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1585 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1586 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1592 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1595 ModestMsgEditWindowPrivate *priv;
1596 gint new_font_index;
1597 ModestMsgEditWindow *window;
1600 window = MODEST_MSG_EDIT_WINDOW (userdata);
1601 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1602 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1604 if (gtk_check_menu_item_get_active (menu_item)) {
1607 label = gtk_bin_get_child (GTK_BIN (menu_item));
1609 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1611 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1612 (gpointer) new_font_index))
1613 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1615 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1616 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1617 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1623 modest_msg_edit_window_set_zoom (ModestWindow *window,
1626 ModestMsgEditWindowPrivate *priv;
1628 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1630 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1631 priv->zoom_level = zoom;
1632 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1636 modest_msg_edit_window_get_zoom (ModestWindow *window)
1638 ModestMsgEditWindowPrivate *priv;
1640 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1642 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1643 return priv->zoom_level;
1647 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1649 ModestWindowPrivate *parent_priv;
1650 GtkRadioAction *zoom_radio_action;
1651 GSList *group, *node;
1653 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1654 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1655 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1657 group = gtk_radio_action_get_group (zoom_radio_action);
1659 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1660 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1664 for (node = group; node != NULL; node = g_slist_next (node)) {
1665 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1666 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1674 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1676 ModestWindowPrivate *parent_priv;
1677 GtkRadioAction *zoom_radio_action;
1678 GSList *group, *node;
1680 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1681 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1682 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1684 group = gtk_radio_action_get_group (zoom_radio_action);
1686 for (node = group; node != NULL; node = g_slist_next (node)) {
1687 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1688 if (node->next != NULL) {
1689 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1692 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1700 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1702 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1703 ModestWindowPrivate *parent_priv;
1704 ModestWindowMgr *mgr;
1705 gboolean is_fullscreen;
1706 GtkAction *fs_toggle_action;
1709 mgr = modest_runtime_get_window_mgr ();
1710 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1712 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1714 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1715 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1716 if (is_fullscreen != active)
1717 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1725 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1727 ModestWindowPrivate *parent_priv;
1728 GtkAction *fs_toggle_action;
1731 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1733 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1734 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1735 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1739 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1742 ModestMsgEditWindowPrivate *priv = NULL;
1743 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1745 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1747 gtk_widget_show (priv->cc_caption);
1749 gtk_widget_hide (priv->cc_caption);
1753 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1756 ModestMsgEditWindowPrivate *priv = NULL;
1757 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1759 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1761 gtk_widget_show (priv->bcc_caption);
1763 gtk_widget_hide (priv->bcc_caption);
1767 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1768 ModestRecptEditor *editor)
1770 ModestMsgEditWindowPrivate *priv;
1772 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1773 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1774 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1776 if (editor == NULL) {
1777 GtkWidget *view_focus;
1778 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1780 /* This code should be kept in sync with ModestRecptEditor. The
1781 textview inside the recpt editor is the one that really gets the
1782 focus. As it's inside a scrolled window, and this one inside the
1783 hbox recpt editor inherits from, we'll need to go up in the
1784 hierarchy to know if the text view is part of the recpt editor
1785 or if it's a different text entry */
1787 if (gtk_widget_get_parent (view_focus)) {
1788 GtkWidget *first_parent;
1790 first_parent = gtk_widget_get_parent (view_focus);
1791 if (gtk_widget_get_parent (first_parent) &&
1792 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1793 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1798 editor = MODEST_RECPT_EDITOR (priv->to_field);
1802 modest_address_book_select_addresses (editor);
1807 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1809 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1811 modest_msg_edit_window_open_addressbook (window, NULL);
1815 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1816 gboolean show_toolbar)
1818 ModestWindowPrivate *parent_priv;
1820 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1821 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1823 /* FIXME: we can not just use the code of
1824 modest_msg_edit_window_setup_toolbar because it has a
1825 mixture of both initialization and creation code. */
1828 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1830 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1834 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1835 TnyHeaderFlags priority_flags)
1837 ModestMsgEditWindowPrivate *priv;
1839 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1841 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1842 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1844 if (priv->priority_flags != priority_flags) {
1846 priv->priority_flags = priority_flags;
1848 switch (priority_flags) {
1849 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1850 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1851 gtk_widget_show (priv->priority_icon);
1853 case TNY_HEADER_FLAG_LOW_PRIORITY:
1854 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1855 gtk_widget_show (priv->priority_icon);
1858 gtk_widget_hide (priv->priority_icon);
1865 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1868 ModestMsgEditWindowPrivate *priv;
1869 gint current_format;
1871 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1873 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1875 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1876 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1878 if (current_format != file_format) {
1879 switch (file_format) {
1880 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1881 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1883 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1887 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1888 response = gtk_dialog_run (GTK_DIALOG (dialog));
1889 gtk_widget_destroy (dialog);
1890 if (response == GTK_RESPONSE_OK)
1891 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1895 update_dimmed (window);
1900 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1903 ModestMsgEditWindowPrivate *priv;
1904 WPTextBufferFormat oldfmt, fmt;
1905 gint old_position = 0;
1909 GdkColor *color = NULL;
1910 gboolean bold, bold_set, italic, italic_set;
1911 gboolean underline, underline_set;
1912 gboolean strikethrough, strikethrough_set;
1913 gboolean position_set;
1914 gboolean font_size_set, font_set, color_set;
1917 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1918 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1920 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
1922 /* First we get the currently selected font information */
1923 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
1924 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
1926 switch (oldfmt.text_position) {
1927 case TEXT_POSITION_NORMAL:
1930 case TEXT_POSITION_SUPERSCRIPT:
1938 g_object_set (G_OBJECT (dialog),
1939 "bold", oldfmt.bold != FALSE,
1940 "bold-set", !oldfmt.cs.bold,
1941 "underline", oldfmt.underline != FALSE,
1942 "underline-set", !oldfmt.cs.underline,
1943 "italic", oldfmt.italic != FALSE,
1944 "italic-set", !oldfmt.cs.italic,
1945 "strikethrough", oldfmt.strikethrough != FALSE,
1946 "strikethrough-set", !oldfmt.cs.strikethrough,
1947 "color", &oldfmt.color,
1948 "color-set", !oldfmt.cs.color,
1949 "size", wp_font_size[oldfmt.font_size],
1950 "size-set", !oldfmt.cs.font_size,
1951 "position", old_position,
1952 "position-set", !oldfmt.cs.text_position,
1953 "family", wp_get_font_name (oldfmt.font),
1954 "family-set", !oldfmt.cs.font,
1957 gtk_widget_show_all (dialog);
1958 response = gtk_dialog_run (GTK_DIALOG (dialog));
1959 if (response == GTK_RESPONSE_OK) {
1961 g_object_get( dialog,
1963 "bold-set", &bold_set,
1964 "underline", &underline,
1965 "underline-set", &underline_set,
1967 "italic-set", &italic_set,
1968 "strikethrough", &strikethrough,
1969 "strikethrough-set", &strikethrough_set,
1971 "color-set", &color_set,
1973 "size-set", &font_size_set,
1974 "family", &font_name,
1975 "family-set", &font_set,
1976 "position", &position,
1977 "position-set", &position_set,
1982 if (response == GTK_RESPONSE_OK) {
1983 memset(&fmt, 0, sizeof(fmt));
1989 fmt.italic = italic;
1990 fmt.cs.italic = TRUE;
1992 if (underline_set) {
1993 fmt.underline = underline;
1994 fmt.cs.underline = TRUE;
1996 if (strikethrough_set) {
1997 fmt.strikethrough = strikethrough;
1998 fmt.cs.strikethrough = TRUE;
2003 ? TEXT_POSITION_NORMAL
2004 : ( ( position == 1 )
2005 ? TEXT_POSITION_SUPERSCRIPT
2006 : TEXT_POSITION_SUBSCRIPT );
2007 fmt.cs.text_position = TRUE;
2011 fmt.cs.color = TRUE;
2014 fmt.font = wp_get_font_index(font_name,
2019 if (font_size_set) {
2020 fmt.font_size = wp_get_font_size_index(
2021 font_size, DEFAULT_FONT_SIZE);
2022 fmt.cs.font_size = TRUE;
2024 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2026 gtk_widget_destroy (dialog);
2028 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2032 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2034 ModestMsgEditWindowPrivate *priv;
2036 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2037 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2039 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2041 update_dimmed (window);
2046 update_dimmed (ModestMsgEditWindow *window)
2048 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2049 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2053 gboolean editor_focused;
2055 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2056 editor_focused = gtk_widget_is_focus (priv->msg_body);
2058 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2059 gtk_action_set_sensitive (action, rich_text && editor_focused);
2060 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2061 gtk_action_set_sensitive (action, rich_text && editor_focused);
2062 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2063 gtk_action_set_sensitive (action, rich_text && editor_focused);
2064 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2065 gtk_action_set_sensitive (action, rich_text && editor_focused);
2066 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2067 gtk_action_set_sensitive (action, rich_text && editor_focused);
2068 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2069 gtk_action_set_sensitive (action, rich_text && editor_focused);
2070 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2071 gtk_action_set_sensitive (action, rich_text && editor_focused);
2072 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2073 gtk_action_set_sensitive (action, rich_text && editor_focused);
2074 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2075 gtk_action_set_sensitive (action, rich_text && editor_focused);
2076 widget = priv->font_color_button;
2077 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2078 widget = priv->font_size_toolitem;
2079 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2080 widget = priv->font_face_toolitem;
2081 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2085 setup_insensitive_handlers (ModestMsgEditWindow *window)
2087 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2088 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2091 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2092 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2093 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2094 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2096 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2097 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2098 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2099 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2100 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2101 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2102 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2103 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2104 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2105 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2106 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2107 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2108 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2109 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2110 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2111 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2112 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2113 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2114 widget = priv->font_color_button;
2115 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2116 widget = priv->font_size_toolitem;
2117 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2118 widget = priv->font_face_toolitem;
2119 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2124 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2126 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2129 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2130 gtk_action_set_sensitive (action, can_undo);
2134 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2137 GtkTextIter match_start, match_end;
2139 if (image_id == NULL)
2142 gtk_text_buffer_get_start_iter (buffer, &iter);
2144 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2145 GSList *tags = gtk_text_iter_get_tags (&match_start);
2147 for (node = tags; node != NULL; node = g_slist_next (node)) {
2148 GtkTextTag *tag = (GtkTextTag *) node->data;
2149 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2150 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2151 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2153 offset = gtk_text_iter_get_offset (&match_start);
2154 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2155 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2163 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2165 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2166 GtkTextIter real_start, real_end;
2167 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2169 if (gtk_text_iter_compare (start, end) > 0) {
2173 real_start = *start;
2177 GSList *tags = gtk_text_iter_get_tags (&real_start);
2179 for (node = tags; node != NULL; node = g_slist_next (node)) {
2180 GtkTextTag *tag = (GtkTextTag *) node->data;
2181 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2182 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2184 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2186 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2189 } while (gtk_text_iter_forward_char (&real_start)&&
2190 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2194 msg_body_focus (GtkWidget *focus,
2195 GdkEventFocus *event,
2199 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2204 to_field_changed (GtkTextBuffer *buffer,
2205 ModestMsgEditWindow *editor)
2207 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2210 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2211 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2212 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2213 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2217 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2219 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2223 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2225 gboolean rich_text, editor_focused;
2227 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2228 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2229 editor_focused = gtk_widget_is_focus (priv->msg_body);
2232 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2233 else if (!editor_focused)
2234 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2238 reset_modified (ModestMsgEditWindow *editor)
2240 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2241 GtkTextBuffer *buffer;
2243 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2244 gtk_text_buffer_set_modified (buffer, FALSE);
2245 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2246 gtk_text_buffer_set_modified (buffer, FALSE);
2247 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2248 gtk_text_buffer_set_modified (buffer, FALSE);
2249 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2253 is_modified (ModestMsgEditWindow *editor)
2255 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2256 GtkTextBuffer *buffer;
2258 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2259 if (gtk_text_buffer_get_modified (buffer))
2261 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2262 if (gtk_text_buffer_get_modified (buffer))
2264 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2265 if (gtk_text_buffer_get_modified (buffer))
2267 if (gtk_text_buffer_get_modified (priv->text_buffer))
2274 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2276 ModestMsgEditWindowPrivate *priv = NULL;
2278 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2279 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2281 /* check if there's no recipient added */
2282 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2283 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2284 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2285 /* no recipient contents, then select contacts */
2286 modest_msg_edit_window_open_addressbook (window, NULL);
2290 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2292 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2294 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2297 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2304 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2305 ModestMsgEditWindow *window)
2307 modest_msg_edit_window_attach_file (window);
2311 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2313 ModestMsgEditWindow *window)
2315 ModestWindowPrivate *parent_priv;
2320 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2321 selection = gtk_clipboard_wait_for_text (clipboard);
2322 focused = gtk_window_get_focus (GTK_WINDOW (window));
2324 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2325 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2326 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2327 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2331 update_window_title (ModestMsgEditWindow *window)
2333 ModestMsgEditWindowPrivate *priv = NULL;
2334 const gchar *subject;
2336 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2337 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2338 if (subject == NULL || subject[0] == '\0')
2339 subject = _("mail_va_new_email");
2341 gtk_window_set_title (GTK_WINDOW (window), subject);
2346 subject_field_changed (GtkEditable *editable,
2347 ModestMsgEditWindow *window)
2349 update_window_title (window);