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->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
956 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
957 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
958 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
960 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
962 gtk_text_buffer_get_bounds (buf, &b, &e);
963 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
965 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
966 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
968 data->html_body = NULL;
970 data->attachments = priv->attachments; /* TODO: copy and free ? */
971 data->priority_flags = priv->priority_flags;
976 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
978 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
981 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
989 g_free (data->subject);
990 g_free (data->plain_body);
991 g_free (data->html_body);
993 /* TODO: Free data->attachments? */
995 g_slice_free (MsgData, data);
999 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1002 ModestMsgEditWindowPrivate *priv = NULL;
1003 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1005 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1007 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1009 return MODEST_MSG_EDIT_FORMAT_HTML;
1011 return MODEST_MSG_EDIT_FORMAT_TEXT;
1015 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1016 ModestMsgEditFormat format)
1018 ModestMsgEditWindowPrivate *priv;
1020 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1021 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1024 case MODEST_MSG_EDIT_FORMAT_HTML:
1025 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1027 case MODEST_MSG_EDIT_FORMAT_TEXT:
1028 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1031 g_return_if_reached ();
1035 ModestMsgEditFormatState *
1036 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1038 ModestMsgEditFormatState *format_state = NULL;
1039 ModestMsgEditWindowPrivate *priv;
1040 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1042 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1043 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1045 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1047 format_state = g_new0 (ModestMsgEditFormatState, 1);
1048 format_state->bold = buffer_format->bold&0x1;
1049 format_state->italics = buffer_format->italic&0x1;
1050 format_state->bullet = buffer_format->bullet&0x1;
1051 format_state->color = buffer_format->color;
1052 format_state->font_size = buffer_format->font_size;
1053 format_state->font_family = wp_get_font_name (buffer_format->font);
1054 format_state->justification = buffer_format->justification;
1055 g_free (buffer_format);
1057 return format_state;
1062 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1063 const ModestMsgEditFormatState *format_state)
1065 ModestMsgEditWindowPrivate *priv;
1066 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1067 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1068 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1069 g_return_if_fail (format_state != NULL);
1071 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1072 gtk_widget_grab_focus (priv->msg_body);
1073 buffer_format->bold = (format_state->bold != FALSE);
1074 buffer_format->italic = (format_state->italics != FALSE);
1075 buffer_format->color = format_state->color;
1076 buffer_format->font_size = format_state->font_size;
1077 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1078 buffer_format->justification = format_state->justification;
1079 buffer_format->bullet = format_state->bullet;
1081 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1083 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1084 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1085 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1086 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1087 buffer_format->cs.font = (buffer_format->font != current_format->font);
1088 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1089 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1091 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1092 if (buffer_format->cs.bold) {
1093 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1095 if (buffer_format->cs.italic) {
1096 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1098 if (buffer_format->cs.color) {
1099 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1101 if (buffer_format->cs.font_size) {
1102 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1104 if (buffer_format->cs.justification) {
1105 switch (buffer_format->justification) {
1106 case GTK_JUSTIFY_LEFT:
1107 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1109 case GTK_JUSTIFY_CENTER:
1110 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1112 case GTK_JUSTIFY_RIGHT:
1113 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1120 if (buffer_format->cs.font) {
1121 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1123 if (buffer_format->cs.bullet) {
1124 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
1126 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1127 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1129 g_free (current_format);
1134 toggle_action_set_active_block_notify (GtkToggleAction *action,
1137 GSList *proxies = NULL;
1139 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1140 proxies != NULL; proxies = g_slist_next (proxies)) {
1141 GtkWidget *widget = (GtkWidget *) proxies->data;
1142 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1145 gtk_toggle_action_set_active (action, value);
1147 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1148 proxies != NULL; proxies = g_slist_next (proxies)) {
1149 GtkWidget *widget = (GtkWidget *) proxies->data;
1150 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1155 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1157 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1159 ModestWindowPrivate *parent_priv;
1160 ModestMsgEditWindowPrivate *priv;
1161 GtkWidget *new_size_menuitem;
1162 GtkWidget *new_font_menuitem;
1164 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1165 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1167 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1168 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1169 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1170 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1172 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1173 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1174 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1177 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1179 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1180 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1182 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1183 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1185 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1186 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1188 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1189 G_CALLBACK (modest_msg_edit_window_color_button_change),
1191 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1192 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1193 G_CALLBACK (modest_msg_edit_window_color_button_change),
1196 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1197 buffer_format->font_size))->data);
1198 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1202 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1203 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1204 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1206 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1207 G_CALLBACK (modest_msg_edit_window_size_change),
1209 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1210 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1211 G_CALLBACK (modest_msg_edit_window_size_change),
1215 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1216 buffer_format->font))->data);
1217 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1221 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1222 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1223 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1225 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1226 G_CALLBACK (modest_msg_edit_window_font_change),
1228 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1229 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1230 G_CALLBACK (modest_msg_edit_window_font_change),
1234 g_free (buffer_format);
1240 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1243 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1244 ModestMsgEditWindowPrivate *priv;
1245 GtkWidget *dialog = NULL;
1247 const GdkColor *new_color = NULL;
1249 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1250 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1252 #ifdef MODEST_HILDON_VERSION_0
1253 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1254 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1256 dialog = hildon_color_chooser_new ();
1257 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1258 #endif /*MODEST_HILDON_VERSION_0*/
1259 g_free (buffer_format);
1261 response = gtk_dialog_run (GTK_DIALOG (dialog));
1263 case GTK_RESPONSE_OK: {
1264 #ifdef MODEST_HILDON_VERSION_0
1265 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1268 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1270 #endif /*MODEST_HILDON_VERSION_0*/
1277 gtk_widget_destroy (dialog);
1279 if (new_color != NULL)
1280 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1285 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1288 ModestMsgEditWindowPrivate *priv;
1289 GtkWidget *dialog = NULL;
1291 GdkColor *old_color = NULL;
1292 const GdkColor *new_color = NULL;
1294 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1295 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1297 #ifdef MODEST_HILDON_VERSION_0
1298 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1299 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1301 dialog = hildon_color_chooser_new ();
1302 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1303 #endif /*MODEST_HILDON_VERSION_9*/
1305 response = gtk_dialog_run (GTK_DIALOG (dialog));
1307 case GTK_RESPONSE_OK: {
1308 #ifdef MODEST_HILDON_VERSION_0
1309 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1312 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1314 #endif /*MODEST_HILDON_VERSION_0*/
1320 gtk_widget_destroy (dialog);
1322 if (new_color != NULL)
1323 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1328 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1331 ModestMsgEditWindowPrivate *priv;
1332 GtkWidget *dialog = NULL;
1334 gchar *filename = NULL;
1336 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1338 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1340 response = gtk_dialog_run (GTK_DIALOG (dialog));
1342 case GTK_RESPONSE_OK:
1343 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1348 gtk_widget_destroy (dialog);
1351 GdkPixbuf *pixbuf = NULL;
1352 GtkTextIter position;
1353 GtkTextMark *insert_mark;
1355 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1358 GdkPixbufFormat *pixbuf_format;
1360 image_file_id = g_open (filename, O_RDONLY, 0);
1361 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1362 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1363 TnyMimePart *image_part;
1364 TnyStream *image_stream;
1370 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1371 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1372 mime_type = mime_types[0];
1374 mime_type = "image/unknown";
1376 image_part = tny_platform_factory_new_mime_part
1377 (modest_runtime_get_platform_factory ());
1378 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1380 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1381 g_strfreev (mime_types);
1383 content_id = g_strdup_printf ("%d", priv->last_cid);
1384 tny_mime_part_set_content_id (image_part, content_id);
1385 g_free (content_id);
1388 basename = g_path_get_basename (filename);
1389 tny_mime_part_set_filename (image_part, basename);
1392 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1393 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1394 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1395 priv->attachments = g_list_prepend (priv->attachments, image_part);
1396 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1398 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1399 gtk_widget_show_all (priv->attachments_caption);
1400 } else if (image_file_id == -1) {
1401 close (image_file_id);
1410 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1413 ModestMsgEditWindowPrivate *priv;
1414 GtkWidget *dialog = NULL;
1416 gchar *filename = NULL;
1418 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1420 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1422 response = gtk_dialog_run (GTK_DIALOG (dialog));
1424 case GTK_RESPONSE_OK:
1425 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1430 gtk_widget_destroy (dialog);
1435 file_id = g_open (filename, O_RDONLY, 0);
1436 if (file_id != -1) {
1437 TnyMimePart *mime_part;
1439 const gchar *mime_type;
1443 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1444 mime_part = tny_platform_factory_new_mime_part
1445 (modest_runtime_get_platform_factory ());
1446 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1448 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1450 content_id = g_strdup_printf ("%d", priv->last_cid);
1451 tny_mime_part_set_content_id (mime_part, content_id);
1452 g_free (content_id);
1455 basename = g_path_get_basename (filename);
1456 tny_mime_part_set_filename (mime_part, basename);
1459 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1460 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1462 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1463 gtk_widget_show_all (priv->attachments_caption);
1464 } else if (file_id == -1) {
1471 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1474 ModestMsgEditWindowPrivate *priv;
1475 gboolean clean_list = FALSE;
1477 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1478 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1480 if (att_list == NULL) {
1481 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1485 if (att_list == NULL) {
1486 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1488 GtkWidget *confirmation_dialog = NULL;
1489 gboolean dialog_response;
1491 if (att_list->next == NULL) {
1492 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1493 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1494 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1497 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1499 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1500 gtk_widget_destroy (confirmation_dialog);
1501 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1503 for (node = att_list; node != NULL; node = g_list_next (node)) {
1504 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1505 const gchar *att_id;
1506 priv->attachments = g_list_remove (priv->attachments, mime_part);
1508 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1510 att_id = tny_mime_part_get_content_id (mime_part);
1512 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1514 g_object_unref (mime_part);
1519 g_list_free (att_list);
1523 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1526 ModestMsgEditWindowPrivate *priv;
1527 GdkColor *new_color;
1528 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1530 #ifdef MODEST_HILDON_VERSION_0
1531 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1534 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1536 #endif /*MODEST_HILDON_VERSION_0*/
1538 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1540 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1545 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1548 ModestMsgEditWindowPrivate *priv;
1549 gint new_size_index;
1550 ModestMsgEditWindow *window;
1553 window = MODEST_MSG_EDIT_WINDOW (userdata);
1554 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1555 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1557 if (gtk_check_menu_item_get_active (menu_item)) {
1560 label = gtk_bin_get_child (GTK_BIN (menu_item));
1562 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1564 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1565 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1566 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1568 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1569 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1570 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1576 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1579 ModestMsgEditWindowPrivate *priv;
1580 gint new_font_index;
1581 ModestMsgEditWindow *window;
1584 window = MODEST_MSG_EDIT_WINDOW (userdata);
1585 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1586 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1588 if (gtk_check_menu_item_get_active (menu_item)) {
1591 label = gtk_bin_get_child (GTK_BIN (menu_item));
1593 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1595 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1596 (gpointer) new_font_index))
1597 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1599 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1600 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1601 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1607 modest_msg_edit_window_set_zoom (ModestWindow *window,
1610 ModestMsgEditWindowPrivate *priv;
1612 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1614 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1615 priv->zoom_level = zoom;
1616 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1620 modest_msg_edit_window_get_zoom (ModestWindow *window)
1622 ModestMsgEditWindowPrivate *priv;
1624 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1626 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1627 return priv->zoom_level;
1631 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1633 ModestWindowPrivate *parent_priv;
1634 GtkRadioAction *zoom_radio_action;
1635 GSList *group, *node;
1637 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1638 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1639 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1641 group = gtk_radio_action_get_group (zoom_radio_action);
1643 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1644 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1648 for (node = group; node != NULL; node = g_slist_next (node)) {
1649 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1650 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1658 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1660 ModestWindowPrivate *parent_priv;
1661 GtkRadioAction *zoom_radio_action;
1662 GSList *group, *node;
1664 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1665 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1666 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1668 group = gtk_radio_action_get_group (zoom_radio_action);
1670 for (node = group; node != NULL; node = g_slist_next (node)) {
1671 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1672 if (node->next != NULL) {
1673 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1676 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1684 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1686 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1687 ModestWindowPrivate *parent_priv;
1688 ModestWindowMgr *mgr;
1689 gboolean is_fullscreen;
1690 GtkAction *fs_toggle_action;
1693 mgr = modest_runtime_get_window_mgr ();
1694 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1696 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1698 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1699 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1700 if (is_fullscreen != active)
1701 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1709 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1711 ModestWindowPrivate *parent_priv;
1712 GtkAction *fs_toggle_action;
1715 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1717 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1718 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1719 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1723 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1726 ModestMsgEditWindowPrivate *priv = NULL;
1727 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1729 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1731 gtk_widget_show (priv->cc_caption);
1733 gtk_widget_hide (priv->cc_caption);
1737 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1740 ModestMsgEditWindowPrivate *priv = NULL;
1741 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1743 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1745 gtk_widget_show (priv->bcc_caption);
1747 gtk_widget_hide (priv->bcc_caption);
1751 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1752 ModestRecptEditor *editor)
1754 ModestMsgEditWindowPrivate *priv;
1756 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1757 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1758 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1760 if (editor == NULL) {
1761 GtkWidget *view_focus;
1762 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1764 /* This code should be kept in sync with ModestRecptEditor. The
1765 textview inside the recpt editor is the one that really gets the
1766 focus. As it's inside a scrolled window, and this one inside the
1767 hbox recpt editor inherits from, we'll need to go up in the
1768 hierarchy to know if the text view is part of the recpt editor
1769 or if it's a different text entry */
1771 if (gtk_widget_get_parent (view_focus)) {
1772 GtkWidget *first_parent;
1774 first_parent = gtk_widget_get_parent (view_focus);
1775 if (gtk_widget_get_parent (first_parent) &&
1776 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1777 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1782 editor = MODEST_RECPT_EDITOR (priv->to_field);
1786 modest_address_book_select_addresses (editor);
1791 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1793 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1795 modest_msg_edit_window_open_addressbook (window, NULL);
1799 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1800 gboolean show_toolbar)
1802 ModestWindowPrivate *parent_priv;
1804 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1805 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1807 /* FIXME: we can not just use the code of
1808 modest_msg_edit_window_setup_toolbar because it has a
1809 mixture of both initialization and creation code. */
1812 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1814 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1818 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1819 TnyHeaderFlags priority_flags)
1821 ModestMsgEditWindowPrivate *priv;
1823 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1825 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1826 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1828 if (priv->priority_flags != priority_flags) {
1830 priv->priority_flags = priority_flags;
1832 switch (priority_flags) {
1833 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1834 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1835 gtk_widget_show (priv->priority_icon);
1837 case TNY_HEADER_FLAG_LOW_PRIORITY:
1838 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1839 gtk_widget_show (priv->priority_icon);
1842 gtk_widget_hide (priv->priority_icon);
1849 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1852 ModestMsgEditWindowPrivate *priv;
1853 gint current_format;
1855 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1857 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1859 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1860 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1862 if (current_format != file_format) {
1863 switch (file_format) {
1864 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1865 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1867 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1871 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1872 response = gtk_dialog_run (GTK_DIALOG (dialog));
1873 gtk_widget_destroy (dialog);
1874 if (response == GTK_RESPONSE_OK)
1875 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1879 update_dimmed (window);
1884 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1887 ModestMsgEditWindowPrivate *priv;
1888 WPTextBufferFormat oldfmt, fmt;
1889 gint old_position = 0;
1893 GdkColor *color = NULL;
1894 gboolean bold, bold_set, italic, italic_set;
1895 gboolean underline, underline_set;
1896 gboolean strikethrough, strikethrough_set;
1897 gboolean position_set;
1898 gboolean font_size_set, font_set, color_set;
1901 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1902 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1904 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
1906 /* First we get the currently selected font information */
1907 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
1908 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
1910 switch (oldfmt.text_position) {
1911 case TEXT_POSITION_NORMAL:
1914 case TEXT_POSITION_SUPERSCRIPT:
1922 g_object_set (G_OBJECT (dialog),
1923 "bold", oldfmt.bold != FALSE,
1924 "bold-set", !oldfmt.cs.bold,
1925 "underline", oldfmt.underline != FALSE,
1926 "underline-set", !oldfmt.cs.underline,
1927 "italic", oldfmt.italic != FALSE,
1928 "italic-set", !oldfmt.cs.italic,
1929 "strikethrough", oldfmt.strikethrough != FALSE,
1930 "strikethrough-set", !oldfmt.cs.strikethrough,
1931 "color", &oldfmt.color,
1932 "color-set", !oldfmt.cs.color,
1933 "size", wp_font_size[oldfmt.font_size],
1934 "size-set", !oldfmt.cs.font_size,
1935 "position", old_position,
1936 "position-set", !oldfmt.cs.text_position,
1937 "family", wp_get_font_name (oldfmt.font),
1938 "family-set", !oldfmt.cs.font,
1941 gtk_widget_show_all (dialog);
1942 response = gtk_dialog_run (GTK_DIALOG (dialog));
1943 if (response == GTK_RESPONSE_OK) {
1945 g_object_get( dialog,
1947 "bold-set", &bold_set,
1948 "underline", &underline,
1949 "underline-set", &underline_set,
1951 "italic-set", &italic_set,
1952 "strikethrough", &strikethrough,
1953 "strikethrough-set", &strikethrough_set,
1955 "color-set", &color_set,
1957 "size-set", &font_size_set,
1958 "family", &font_name,
1959 "family-set", &font_set,
1960 "position", &position,
1961 "position-set", &position_set,
1966 if (response == GTK_RESPONSE_OK) {
1967 memset(&fmt, 0, sizeof(fmt));
1973 fmt.italic = italic;
1974 fmt.cs.italic = TRUE;
1976 if (underline_set) {
1977 fmt.underline = underline;
1978 fmt.cs.underline = TRUE;
1980 if (strikethrough_set) {
1981 fmt.strikethrough = strikethrough;
1982 fmt.cs.strikethrough = TRUE;
1987 ? TEXT_POSITION_NORMAL
1988 : ( ( position == 1 )
1989 ? TEXT_POSITION_SUPERSCRIPT
1990 : TEXT_POSITION_SUBSCRIPT );
1991 fmt.cs.text_position = TRUE;
1995 fmt.cs.color = TRUE;
1998 fmt.font = wp_get_font_index(font_name,
2003 if (font_size_set) {
2004 fmt.font_size = wp_get_font_size_index(
2005 font_size, DEFAULT_FONT_SIZE);
2006 fmt.cs.font_size = TRUE;
2008 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2010 gtk_widget_destroy (dialog);
2012 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2016 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2018 ModestMsgEditWindowPrivate *priv;
2020 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2021 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2023 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2025 update_dimmed (window);
2030 update_dimmed (ModestMsgEditWindow *window)
2032 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2033 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2037 gboolean editor_focused;
2039 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2040 editor_focused = gtk_widget_is_focus (priv->msg_body);
2042 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2043 gtk_action_set_sensitive (action, rich_text && editor_focused);
2044 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2045 gtk_action_set_sensitive (action, rich_text && editor_focused);
2046 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2047 gtk_action_set_sensitive (action, rich_text && editor_focused);
2048 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2049 gtk_action_set_sensitive (action, rich_text && editor_focused);
2050 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2051 gtk_action_set_sensitive (action, rich_text && editor_focused);
2052 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2053 gtk_action_set_sensitive (action, rich_text && editor_focused);
2054 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2055 gtk_action_set_sensitive (action, rich_text && editor_focused);
2056 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2057 gtk_action_set_sensitive (action, rich_text && editor_focused);
2058 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2059 gtk_action_set_sensitive (action, rich_text && editor_focused);
2060 widget = priv->font_color_button;
2061 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2062 widget = priv->font_size_toolitem;
2063 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2064 widget = priv->font_face_toolitem;
2065 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2069 setup_insensitive_handlers (ModestMsgEditWindow *window)
2071 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2072 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2075 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2076 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2077 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2078 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2080 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2081 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2082 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2083 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2084 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2085 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2086 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2087 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2088 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2089 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2090 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2091 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2092 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2093 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2094 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2095 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2096 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2097 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2098 widget = priv->font_color_button;
2099 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2100 widget = priv->font_size_toolitem;
2101 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2102 widget = priv->font_face_toolitem;
2103 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2108 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2110 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2113 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2114 gtk_action_set_sensitive (action, can_undo);
2118 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2121 GtkTextIter match_start, match_end;
2123 if (image_id == NULL)
2126 gtk_text_buffer_get_start_iter (buffer, &iter);
2128 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2129 GSList *tags = gtk_text_iter_get_tags (&match_start);
2131 for (node = tags; node != NULL; node = g_slist_next (node)) {
2132 GtkTextTag *tag = (GtkTextTag *) node->data;
2133 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2134 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2135 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2137 offset = gtk_text_iter_get_offset (&match_start);
2138 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2139 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2147 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2149 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2150 GtkTextIter real_start, real_end;
2151 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2153 if (gtk_text_iter_compare (start, end) > 0) {
2157 real_start = *start;
2161 GSList *tags = gtk_text_iter_get_tags (&real_start);
2163 for (node = tags; node != NULL; node = g_slist_next (node)) {
2164 GtkTextTag *tag = (GtkTextTag *) node->data;
2165 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2166 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2168 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2170 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2173 } while (gtk_text_iter_forward_char (&real_start)&&
2174 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2178 msg_body_focus (GtkWidget *focus,
2179 GdkEventFocus *event,
2183 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2188 to_field_changed (GtkTextBuffer *buffer,
2189 ModestMsgEditWindow *editor)
2191 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2194 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2195 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2196 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2197 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2201 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2203 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2207 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2209 gboolean rich_text, editor_focused;
2211 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2212 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2213 editor_focused = gtk_widget_is_focus (priv->msg_body);
2216 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2217 else if (!editor_focused)
2218 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2222 reset_modified (ModestMsgEditWindow *editor)
2224 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2225 GtkTextBuffer *buffer;
2227 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2228 gtk_text_buffer_set_modified (buffer, FALSE);
2229 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2230 gtk_text_buffer_set_modified (buffer, FALSE);
2231 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2232 gtk_text_buffer_set_modified (buffer, FALSE);
2233 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2237 is_modified (ModestMsgEditWindow *editor)
2239 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2240 GtkTextBuffer *buffer;
2242 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2243 if (gtk_text_buffer_get_modified (buffer))
2245 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2246 if (gtk_text_buffer_get_modified (buffer))
2248 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2249 if (gtk_text_buffer_get_modified (buffer))
2251 if (gtk_text_buffer_get_modified (priv->text_buffer))
2258 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2260 ModestMsgEditWindowPrivate *priv = NULL;
2262 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2263 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2265 /* check if there's no recipient added */
2266 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2267 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2268 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2269 /* no recipient contents, then select contacts */
2270 modest_msg_edit_window_open_addressbook (window, NULL);
2274 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2276 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2278 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2281 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2288 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2289 ModestMsgEditWindow *window)
2291 modest_msg_edit_window_attach_file (window);
2295 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2297 ModestMsgEditWindow *window)
2299 ModestWindowPrivate *parent_priv;
2304 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2305 selection = gtk_clipboard_wait_for_text (clipboard);
2306 focused = gtk_window_get_focus (GTK_WINDOW (window));
2308 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2309 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2310 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2311 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2315 update_window_title (ModestMsgEditWindow *window)
2317 ModestMsgEditWindowPrivate *priv = NULL;
2318 const gchar *subject;
2320 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2321 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2322 if (subject == NULL || subject[0] == '\0')
2323 subject = _("mail_va_new_email");
2325 gtk_window_set_title (GTK_WINDOW (window), subject);
2330 subject_field_changed (GtkEditable *editable,
2331 ModestMsgEditWindow *window)
2333 update_window_title (window);