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 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
94 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
96 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
98 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
99 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
100 GdkEventWindowState *event,
102 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
103 ModestRecptEditor *editor);
104 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
105 ModestMsgEditWindow *window);
107 /* ModestWindow methods implementation */
108 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
109 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
110 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
111 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
112 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
113 gboolean show_toolbar);
114 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
116 ModestMsgEditWindow *window);
117 static void update_dimmed (ModestMsgEditWindow *window);
120 /* list my signals */
127 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
128 struct _ModestMsgEditWindowPrivate {
130 GtkWidget *header_box;
132 ModestPairList *from_field_protos;
133 GtkWidget *from_field;
137 GtkWidget *bcc_field;
138 GtkWidget *subject_field;
139 GtkWidget *attachments_view;
140 GtkWidget *priority_icon;
141 GtkWidget *add_attachment_button;
143 GtkWidget *cc_caption;
144 GtkWidget *bcc_caption;
145 GtkWidget *attachments_caption;
147 GtkTextBuffer *text_buffer;
149 GtkWidget *font_size_toolitem;
150 GtkWidget *font_face_toolitem;
151 GtkWidget *font_color_button;
152 GSList *font_items_group;
153 GtkWidget *font_tool_button_label;
154 GSList *size_items_group;
155 GtkWidget *size_tool_button_label;
162 TnyHeaderFlags priority_flags;
166 gulong clipboard_change_handler_id;
171 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
172 MODEST_TYPE_MSG_EDIT_WINDOW, \
173 ModestMsgEditWindowPrivate))
175 static GtkWindowClass *parent_class = NULL;
177 /* uncomment the following if you have defined any signals */
178 /* static guint signals[LAST_SIGNAL] = {0}; */
181 modest_msg_edit_window_get_type (void)
183 static GType my_type = 0;
185 static const GTypeInfo my_info = {
186 sizeof(ModestMsgEditWindowClass),
187 NULL, /* base init */
188 NULL, /* base finalize */
189 (GClassInitFunc) modest_msg_edit_window_class_init,
190 NULL, /* class finalize */
191 NULL, /* class data */
192 sizeof(ModestMsgEditWindow),
194 (GInstanceInitFunc) modest_msg_edit_window_init,
197 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
198 "ModestMsgEditWindow",
201 wp_text_buffer_library_init ();
207 save_state (ModestWindow *self)
209 modest_widget_memory_save (modest_runtime_get_conf(),
210 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
215 restore_settings (ModestMsgEditWindow *self)
217 modest_widget_memory_restore (modest_runtime_get_conf(),
218 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
223 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
225 GObjectClass *gobject_class;
226 ModestWindowClass *modest_window_class;
227 gobject_class = (GObjectClass*) klass;
228 modest_window_class = (ModestWindowClass*) klass;
230 parent_class = g_type_class_peek_parent (klass);
231 gobject_class->finalize = modest_msg_edit_window_finalize;
233 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
234 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
235 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
236 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
237 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
239 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
241 modest_window_class->save_state_func = save_state;
245 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
247 ModestMsgEditWindowPrivate *priv;
248 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
250 priv->msg_body = NULL;
251 priv->from_field = NULL;
252 priv->to_field = NULL;
253 priv->cc_field = NULL;
254 priv->bcc_field = NULL;
255 priv->subject_field = NULL;
256 priv->attachments = NULL;
258 priv->zoom_level = 1.0;
260 priv->cc_caption = NULL;
261 priv->bcc_caption = NULL;
263 priv->priority_flags = 0;
265 priv->draft_msg = NULL;
266 priv->clipboard_change_handler_id = 0;
270 /* FIXME: this is a dup from the one in gtk/ */
273 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
275 static ModestPairList*
276 get_transports (void)
278 GSList *transports = NULL;
280 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
281 GSList *accounts = modest_account_mgr_account_names (account_mgr,
282 TRUE /* only enabled accounts. */);
284 GSList *cursor = accounts;
286 const gchar *account_name = cursor->data;
287 gchar *from_string = NULL;
289 from_string = modest_account_mgr_get_from_string (account_mgr,
293 if (from_string && account_name) {
294 gchar *name = g_strdup (account_name);
295 ModestPair *pair = modest_pair_new ((gpointer) name,
296 (gpointer) from_string , TRUE);
297 transports = g_slist_prepend (transports, pair);
300 cursor = cursor->next;
302 g_slist_free (accounts);
308 init_window (ModestMsgEditWindow *obj)
310 GtkWidget *from_caption, *to_caption, *subject_caption;
311 GtkWidget *main_vbox;
312 ModestMsgEditWindowPrivate *priv;
314 GtkSizeGroup *size_group;
316 GtkWidget *scroll_area;
317 GtkWidget *subject_box;
318 GtkWidget *attachment_icon;
320 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
322 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
324 /* Note: This ModestPairList* must exist for as long as the combo
325 * that uses it, because the ModestComboBox uses the ID opaquely,
326 * so it can't know how to manage its memory. */
327 priv->from_field_protos = get_transports ();
329 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
331 priv->to_field = modest_recpt_editor_new ();
332 priv->cc_field = modest_recpt_editor_new ();
333 priv->bcc_field = modest_recpt_editor_new ();
334 subject_box = gtk_hbox_new (FALSE, 0);
335 priv->priority_icon = gtk_image_new ();
336 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
337 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
338 g_object_set (G_OBJECT (priv->subject_field), "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
339 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
340 priv->add_attachment_button = gtk_button_new ();
341 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
342 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
343 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
344 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
345 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
346 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
347 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
348 priv->attachments_view = modest_attachments_view_new (NULL);
350 priv->header_box = gtk_vbox_new (FALSE, 0);
352 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
353 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
354 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
355 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
356 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
357 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
358 g_object_unref (size_group);
360 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
361 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
362 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
363 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
364 gtk_size_group_add_widget (size_group, priv->subject_field);
365 gtk_size_group_add_widget (size_group, priv->attachments_view);
366 g_object_unref (size_group);
368 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
369 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
370 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
371 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
372 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
373 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
374 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
377 priv->msg_body = wp_text_view_new ();
378 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
379 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
380 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
381 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
382 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
383 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
385 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
386 G_CALLBACK (text_buffer_refresh_attributes), obj);
387 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
388 G_CALLBACK (text_buffer_delete_range), obj);
389 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
390 G_CALLBACK (text_buffer_can_undo), obj);
391 g_signal_connect (G_OBJECT (obj), "window-state-event",
392 G_CALLBACK (modest_msg_edit_window_window_state_event),
394 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
395 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
396 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
397 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
398 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
399 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
401 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
402 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
404 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
405 G_CALLBACK (msg_body_focus), obj);
406 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
407 G_CALLBACK (msg_body_focus), obj);
408 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
409 "changed", G_CALLBACK (to_field_changed), obj);
410 to_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
412 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
413 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
414 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
416 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
418 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
419 frame = gtk_frame_new (NULL);
420 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
422 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
423 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
424 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
426 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL))
427 gtk_widget_hide (priv->cc_field);
428 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL))
429 gtk_widget_hide (priv->bcc_field);
431 gtk_container_add (GTK_CONTAINER(obj), priv->scroll);
432 scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
433 gtk_container_add (GTK_CONTAINER (frame), scroll_area);
434 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
435 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
437 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
438 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
444 modest_msg_edit_window_finalize (GObject *obj)
446 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
449 if (priv->clipboard_change_handler_id > 0) {
450 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
451 priv->clipboard_change_handler_id = 0;
454 /* This had to stay alive for as long as the combobox that used it: */
455 modest_pair_list_free (priv->from_field_protos);
457 G_OBJECT_CLASS(parent_class)->finalize (obj);
461 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
463 GtkWidget *close_dialog;
464 ModestMsgEditWindowPrivate *priv;
467 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
468 modest_window_save_state (MODEST_WINDOW (self));
469 if (is_modified (self)) {
470 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
471 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
472 gtk_widget_destroy (close_dialog);
474 if (response != GTK_RESPONSE_CANCEL) {
475 modest_ui_actions_on_save_to_drafts (NULL, self);
478 /* /\* remove old message from drafts *\/ */
479 /* if (priv->draft_msg) { */
480 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
481 /* TnyAccount *account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(), */
483 /* TNY_ACCOUNT_TYPE_STORE); */
484 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
485 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
486 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
487 /* tny_folder_remove_msg (folder, header, NULL); */
488 /* g_object_unref (folder); */
489 /* g_object_unref (header); */
490 /* g_object_unref (priv->draft_msg); */
491 /* priv->draft_msg = NULL; */
493 gtk_widget_destroy (GTK_WIDGET (self));
499 menubar_to_menu (GtkUIManager *ui_manager)
501 GtkWidget *main_menu;
505 /* Create new main menu */
506 main_menu = gtk_menu_new();
508 /* Get the menubar from the UI manager */
509 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
511 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
515 menu = GTK_WIDGET (iter->data);
516 gtk_widget_reparent(menu, main_menu);
518 iter = g_list_next (iter);
525 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
528 const gchar *to, *cc, *bcc, *subject;
530 ModestMsgEditWindowPrivate *priv;
533 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
534 g_return_if_fail (TNY_IS_MSG (msg));
536 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
538 header = tny_msg_get_header (msg);
539 to = tny_header_get_to (header);
540 cc = tny_header_get_cc (header);
541 bcc = tny_header_get_bcc (header);
542 subject = tny_header_get_subject (header);
545 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
547 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
549 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
551 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
553 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
554 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
555 body = modest_tny_msg_get_body (msg, FALSE);
557 if ((body == NULL)||(body[0] == '\0')) {
559 body = modest_text_utils_convert_to_html ("");
561 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
562 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
565 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
568 /* Get the default format required from configuration */
569 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
570 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
573 /* Set the default focus depending on having already a To: field or not */
574 if ((!to)||(*to == '\0')) {
575 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
577 gtk_widget_grab_focus (priv->msg_body);
580 /* TODO: lower priority, select in the From: combo to the
581 value that comes from msg <- not sure, should it be
584 /* Add attachments to the view */
585 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
586 if (priv->attachments == NULL)
587 gtk_widget_hide_all (priv->attachments_caption);
589 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
590 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
592 reset_modified (self);
594 update_dimmed (self);
595 text_buffer_can_undo (priv->text_buffer, FALSE, self);
597 priv->draft_msg = msg;
601 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
604 GList *item_children, *node;
605 GtkWidget *bin_child;
607 bin_child = gtk_bin_get_child (GTK_BIN(item));
609 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
611 for (node = item_children; node != NULL; node = g_list_next (node)) {
612 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
613 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
616 g_list_free (item_children);
620 menu_tool_button_dont_expand (GtkMenuToolButton *item)
623 GList *item_children, *node;
625 box = gtk_bin_get_child (GTK_BIN (item));
626 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
627 item_children = gtk_container_get_children (GTK_CONTAINER (box));
629 for (node = item_children; node != NULL; node = g_list_next (node)) {
630 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
631 if (GTK_IS_TOGGLE_BUTTON (node->data))
632 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
633 else if (GTK_IS_BUTTON (node->data))
634 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
636 g_list_free (item_children);
641 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
643 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
644 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
645 GtkWidget *placeholder;
646 GtkWidget *tool_item;
651 GtkWidget *sizes_menu;
652 GtkWidget *fonts_menu;
653 GSList *radio_group = NULL;
658 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
659 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
661 /* should we hide the toolbar? */
662 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
663 gtk_widget_hide (parent_priv->toolbar);
665 /* Font color placeholder */
666 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
667 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
670 tool_item = GTK_WIDGET (gtk_tool_item_new ());
671 priv->font_color_button = hildon_color_button_new ();
672 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
673 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
674 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
675 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
676 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
677 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
678 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
680 /* Font size and face placeholder */
681 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
682 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
684 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
685 priv->size_tool_button_label = gtk_label_new (NULL);
686 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
687 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
688 size_text,"</span>", NULL);
689 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
691 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
692 sizes_menu = gtk_menu_new ();
693 priv->size_items_group = NULL;
695 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
696 GtkWidget *size_menu_item;
698 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
699 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
700 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
701 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
702 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
703 gtk_widget_show (size_menu_item);
705 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
709 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
710 GtkWidget *item = (GtkWidget *) node->data;
711 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
715 priv->size_items_group = g_slist_reverse (priv->size_items_group);
716 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
717 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
718 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
719 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
720 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
721 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
722 priv->font_size_toolitem = tool_item;
725 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
726 priv->font_tool_button_label = gtk_label_new (NULL);
727 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
728 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
730 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
731 fonts_menu = gtk_menu_new ();
732 priv->font_items_group = NULL;
734 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
735 GtkWidget *font_menu_item;
736 GtkWidget *child_label;
738 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
739 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
740 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
741 wp_get_font_name (font_index), "</span>", NULL);
742 gtk_label_set_markup (GTK_LABEL (child_label), markup);
745 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
746 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
747 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
748 gtk_widget_show (font_menu_item);
750 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
753 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
754 GtkWidget *item = (GtkWidget *) node->data;
755 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
758 priv->font_items_group = g_slist_reverse (priv->font_items_group);
759 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
760 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
761 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
762 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
763 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
764 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
765 priv->font_face_toolitem = tool_item;
767 /* Set expand and homogeneous for remaining items */
768 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
769 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
770 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
771 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
772 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
773 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
774 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
775 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
776 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
784 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
787 ModestWindowPrivate *parent_priv;
788 ModestMsgEditWindowPrivate *priv;
789 GtkActionGroup *action_group;
790 GError *error = NULL;
791 GdkPixbuf *window_icon = NULL;
794 gboolean prefer_formatted;
797 g_return_val_if_fail (msg, NULL);
799 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
801 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
802 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
804 parent_priv->ui_manager = gtk_ui_manager_new();
805 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
806 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
808 /* Add common actions */
809 gtk_action_group_add_actions (action_group,
810 modest_msg_edit_action_entries,
811 G_N_ELEMENTS (modest_msg_edit_action_entries),
813 gtk_action_group_add_toggle_actions (action_group,
814 modest_msg_edit_toggle_action_entries,
815 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
817 gtk_action_group_add_radio_actions (action_group,
818 modest_msg_edit_alignment_radio_action_entries,
819 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
821 G_CALLBACK (modest_ui_actions_on_change_justify),
823 gtk_action_group_add_radio_actions (action_group,
824 modest_msg_edit_zoom_action_entries,
825 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
827 G_CALLBACK (modest_ui_actions_on_change_zoom),
829 gtk_action_group_add_radio_actions (action_group,
830 modest_msg_edit_priority_action_entries,
831 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
833 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
835 gtk_action_group_add_radio_actions (action_group,
836 modest_msg_edit_file_format_action_entries,
837 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
838 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
839 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
841 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
842 g_object_unref (action_group);
844 /* Load the UI definition */
845 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml", &error);
847 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
848 g_clear_error (&error);
851 /* Add accelerators */
852 gtk_window_add_accel_group (GTK_WINDOW (obj),
853 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
856 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
857 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
860 init_window (MODEST_MSG_EDIT_WINDOW(obj));
862 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
864 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
865 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
867 g_signal_connect (G_OBJECT(obj), "delete-event",
868 G_CALLBACK(on_delete_event), obj);
870 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
872 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
874 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
876 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
878 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
880 /* Set window icon */
881 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
882 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
884 /* Dim at start clipboard actions */
885 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
886 gtk_action_set_sensitive (action, FALSE);
887 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
888 gtk_action_set_sensitive (action, FALSE);
890 /* Setup the file format */
891 conf = modest_runtime_get_conf ();
892 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
894 g_clear_error (&error);
895 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
897 file_format = (prefer_formatted) ?
898 MODEST_FILE_FORMAT_FORMATTED_TEXT :
899 MODEST_FILE_FORMAT_PLAIN_TEXT;
900 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
902 return (ModestWindow*) obj;
906 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
908 GString **string_buffer = (GString **) user_data;
910 *string_buffer = g_string_append (*string_buffer, buffer);
916 * @result: A new string which should be freed with g_free().
919 get_formatted_data (ModestMsgEditWindow *edit_window)
921 ModestMsgEditWindowPrivate *priv;
922 GString *string_buffer = g_string_new ("");
924 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
926 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
928 return g_string_free (string_buffer, FALSE);
933 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
936 const gchar *account_name;
937 ModestMsgEditWindowPrivate *priv;
939 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
941 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
943 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
944 g_return_val_if_fail (account_name, NULL);
947 /* don't free these (except from) */
948 data = g_slice_new0 (MsgData);
949 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
951 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
952 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
953 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
954 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
956 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
958 gtk_text_buffer_get_bounds (buf, &b, &e);
959 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
961 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
962 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
964 data->html_body = NULL;
966 data->attachments = priv->attachments; /* TODO: copy and free ? */
967 data->priority_flags = priv->priority_flags;
972 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
974 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
977 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
985 g_free (data->subject);
986 g_free (data->plain_body);
987 g_free (data->html_body);
989 /* TODO: Free data->attachments? */
991 g_slice_free (MsgData, data);
995 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
998 ModestMsgEditWindowPrivate *priv = NULL;
999 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1001 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1003 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1005 return MODEST_MSG_EDIT_FORMAT_HTML;
1007 return MODEST_MSG_EDIT_FORMAT_TEXT;
1011 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1012 ModestMsgEditFormat format)
1014 ModestMsgEditWindowPrivate *priv;
1016 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1017 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1020 case MODEST_MSG_EDIT_FORMAT_HTML:
1021 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1023 case MODEST_MSG_EDIT_FORMAT_TEXT:
1024 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1027 g_return_if_reached ();
1031 ModestMsgEditFormatState *
1032 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1034 ModestMsgEditFormatState *format_state = NULL;
1035 ModestMsgEditWindowPrivate *priv;
1036 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1038 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1039 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1041 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1043 format_state = g_new0 (ModestMsgEditFormatState, 1);
1044 format_state->bold = buffer_format->bold&0x1;
1045 format_state->italics = buffer_format->italic&0x1;
1046 format_state->bullet = buffer_format->bullet&0x1;
1047 format_state->color = buffer_format->color;
1048 format_state->font_size = buffer_format->font_size;
1049 format_state->font_family = wp_get_font_name (buffer_format->font);
1050 format_state->justification = buffer_format->justification;
1051 g_free (buffer_format);
1053 return format_state;
1058 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1059 const ModestMsgEditFormatState *format_state)
1061 ModestMsgEditWindowPrivate *priv;
1062 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1063 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1064 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1065 g_return_if_fail (format_state != NULL);
1067 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1068 gtk_widget_grab_focus (priv->msg_body);
1069 buffer_format->bold = (format_state->bold != FALSE);
1070 buffer_format->italic = (format_state->italics != FALSE);
1071 buffer_format->color = format_state->color;
1072 buffer_format->font_size = format_state->font_size;
1073 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1074 buffer_format->justification = format_state->justification;
1075 buffer_format->bullet = format_state->bullet;
1077 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1079 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1080 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1081 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1082 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1083 buffer_format->cs.font = (buffer_format->font != current_format->font);
1084 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1085 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1087 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1088 if (buffer_format->cs.bold) {
1089 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1091 if (buffer_format->cs.italic) {
1092 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1094 if (buffer_format->cs.color) {
1095 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1097 if (buffer_format->cs.font_size) {
1098 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1100 if (buffer_format->cs.justification) {
1101 switch (buffer_format->justification) {
1102 case GTK_JUSTIFY_LEFT:
1103 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1105 case GTK_JUSTIFY_CENTER:
1106 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1108 case GTK_JUSTIFY_RIGHT:
1109 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1116 if (buffer_format->cs.font) {
1117 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1119 if (buffer_format->cs.bullet) {
1120 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
1122 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1123 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1125 g_free (current_format);
1130 toggle_action_set_active_block_notify (GtkToggleAction *action,
1133 GSList *proxies = NULL;
1135 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1136 proxies != NULL; proxies = g_slist_next (proxies)) {
1137 GtkWidget *widget = (GtkWidget *) proxies->data;
1138 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1141 gtk_toggle_action_set_active (action, value);
1143 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1144 proxies != NULL; proxies = g_slist_next (proxies)) {
1145 GtkWidget *widget = (GtkWidget *) proxies->data;
1146 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1151 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1153 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1155 ModestWindowPrivate *parent_priv;
1156 ModestMsgEditWindowPrivate *priv;
1157 GtkWidget *new_size_menuitem;
1158 GtkWidget *new_font_menuitem;
1160 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1161 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1163 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1164 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1165 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1166 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1168 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1169 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1170 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1173 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1175 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1176 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1178 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1179 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1181 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1182 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1184 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1185 G_CALLBACK (modest_msg_edit_window_color_button_change),
1187 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1188 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1189 G_CALLBACK (modest_msg_edit_window_color_button_change),
1192 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1193 buffer_format->font_size))->data);
1194 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1198 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1199 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1200 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1202 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1203 G_CALLBACK (modest_msg_edit_window_size_change),
1205 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1206 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1207 G_CALLBACK (modest_msg_edit_window_size_change),
1211 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1212 buffer_format->font))->data);
1213 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1217 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1218 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1219 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1221 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1222 G_CALLBACK (modest_msg_edit_window_font_change),
1224 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1225 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1226 G_CALLBACK (modest_msg_edit_window_font_change),
1230 g_free (buffer_format);
1236 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1239 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1240 ModestMsgEditWindowPrivate *priv;
1241 GtkWidget *dialog = NULL;
1243 const GdkColor *new_color = NULL;
1245 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1246 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1248 #ifdef MODEST_HILDON_VERSION_0
1249 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1250 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1252 dialog = hildon_color_chooser_new ();
1253 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1254 #endif /*MODEST_HILDON_VERSION_0*/
1255 g_free (buffer_format);
1257 response = gtk_dialog_run (GTK_DIALOG (dialog));
1259 case GTK_RESPONSE_OK: {
1260 #ifdef MODEST_HILDON_VERSION_0
1261 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1264 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1266 #endif /*MODEST_HILDON_VERSION_0*/
1273 gtk_widget_destroy (dialog);
1275 if (new_color != NULL)
1276 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1281 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1284 ModestMsgEditWindowPrivate *priv;
1285 GtkWidget *dialog = NULL;
1287 GdkColor *old_color = NULL;
1288 const GdkColor *new_color = NULL;
1290 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1291 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1293 #ifdef MODEST_HILDON_VERSION_0
1294 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1295 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1297 dialog = hildon_color_chooser_new ();
1298 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1299 #endif /*MODEST_HILDON_VERSION_9*/
1301 response = gtk_dialog_run (GTK_DIALOG (dialog));
1303 case GTK_RESPONSE_OK: {
1304 #ifdef MODEST_HILDON_VERSION_0
1305 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1308 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1310 #endif /*MODEST_HILDON_VERSION_0*/
1316 gtk_widget_destroy (dialog);
1318 if (new_color != NULL)
1319 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1324 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1327 ModestMsgEditWindowPrivate *priv;
1328 GtkWidget *dialog = NULL;
1330 gchar *filename = NULL;
1332 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1334 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1336 response = gtk_dialog_run (GTK_DIALOG (dialog));
1338 case GTK_RESPONSE_OK:
1339 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1344 gtk_widget_destroy (dialog);
1347 GdkPixbuf *pixbuf = NULL;
1348 GtkTextIter position;
1349 GtkTextMark *insert_mark;
1351 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1354 GdkPixbufFormat *pixbuf_format;
1356 image_file_id = g_open (filename, O_RDONLY, 0);
1357 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1358 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1359 TnyMimePart *image_part;
1360 TnyStream *image_stream;
1366 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1367 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1368 mime_type = mime_types[0];
1370 mime_type = "image/unknown";
1372 image_part = tny_platform_factory_new_mime_part
1373 (modest_runtime_get_platform_factory ());
1374 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1376 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1377 g_strfreev (mime_types);
1379 content_id = g_strdup_printf ("%d", priv->last_cid);
1380 tny_mime_part_set_content_id (image_part, content_id);
1381 g_free (content_id);
1384 basename = g_path_get_basename (filename);
1385 tny_mime_part_set_filename (image_part, basename);
1388 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1389 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1390 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1391 priv->attachments = g_list_prepend (priv->attachments, image_part);
1392 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1394 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1395 gtk_widget_show_all (priv->attachments_caption);
1396 } else if (image_file_id == -1) {
1397 close (image_file_id);
1406 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1409 ModestMsgEditWindowPrivate *priv;
1410 GtkWidget *dialog = NULL;
1412 gchar *filename = NULL;
1414 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1416 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1418 response = gtk_dialog_run (GTK_DIALOG (dialog));
1420 case GTK_RESPONSE_OK:
1421 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1426 gtk_widget_destroy (dialog);
1431 file_id = g_open (filename, O_RDONLY, 0);
1432 if (file_id != -1) {
1433 TnyMimePart *mime_part;
1435 const gchar *mime_type;
1439 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1440 mime_part = tny_platform_factory_new_mime_part
1441 (modest_runtime_get_platform_factory ());
1442 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1444 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1446 content_id = g_strdup_printf ("%d", priv->last_cid);
1447 tny_mime_part_set_content_id (mime_part, content_id);
1448 g_free (content_id);
1451 basename = g_path_get_basename (filename);
1452 tny_mime_part_set_filename (mime_part, basename);
1455 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1456 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1458 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1459 gtk_widget_show_all (priv->attachments_caption);
1460 } else if (file_id == -1) {
1467 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1470 ModestMsgEditWindowPrivate *priv;
1471 gboolean clean_list = FALSE;
1473 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1474 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1476 if (att_list == NULL) {
1477 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1481 if (att_list == NULL) {
1482 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1484 GtkWidget *confirmation_dialog = NULL;
1485 gboolean dialog_response;
1487 if (att_list->next == NULL) {
1488 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1489 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1490 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1493 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1495 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1496 gtk_widget_destroy (confirmation_dialog);
1497 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1499 for (node = att_list; node != NULL; node = g_list_next (node)) {
1500 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1501 const gchar *att_id;
1502 priv->attachments = g_list_remove (priv->attachments, mime_part);
1504 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1506 att_id = tny_mime_part_get_content_id (mime_part);
1508 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1510 g_object_unref (mime_part);
1515 g_list_free (att_list);
1519 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1522 ModestMsgEditWindowPrivate *priv;
1523 GdkColor *new_color;
1524 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1526 #ifdef MODEST_HILDON_VERSION_0
1527 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1530 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1532 #endif /*MODEST_HILDON_VERSION_0*/
1534 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1536 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1541 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1544 ModestMsgEditWindowPrivate *priv;
1545 gint new_size_index;
1546 ModestMsgEditWindow *window;
1549 window = MODEST_MSG_EDIT_WINDOW (userdata);
1550 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1551 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1553 if (gtk_check_menu_item_get_active (menu_item)) {
1556 label = gtk_bin_get_child (GTK_BIN (menu_item));
1558 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1560 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1561 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1562 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1564 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1565 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1566 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1572 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1575 ModestMsgEditWindowPrivate *priv;
1576 gint new_font_index;
1577 ModestMsgEditWindow *window;
1580 window = MODEST_MSG_EDIT_WINDOW (userdata);
1581 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1582 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1584 if (gtk_check_menu_item_get_active (menu_item)) {
1587 label = gtk_bin_get_child (GTK_BIN (menu_item));
1589 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1591 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1592 (gpointer) new_font_index))
1593 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1595 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1596 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1597 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1603 modest_msg_edit_window_set_zoom (ModestWindow *window,
1606 ModestMsgEditWindowPrivate *priv;
1608 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1610 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1611 priv->zoom_level = zoom;
1612 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1616 modest_msg_edit_window_get_zoom (ModestWindow *window)
1618 ModestMsgEditWindowPrivate *priv;
1620 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1622 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1623 return priv->zoom_level;
1627 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1629 ModestWindowPrivate *parent_priv;
1630 GtkRadioAction *zoom_radio_action;
1631 GSList *group, *node;
1633 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1634 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1635 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1637 group = gtk_radio_action_get_group (zoom_radio_action);
1639 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1640 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1644 for (node = group; node != NULL; node = g_slist_next (node)) {
1645 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1646 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1654 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1656 ModestWindowPrivate *parent_priv;
1657 GtkRadioAction *zoom_radio_action;
1658 GSList *group, *node;
1660 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1661 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1662 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1664 group = gtk_radio_action_get_group (zoom_radio_action);
1666 for (node = group; node != NULL; node = g_slist_next (node)) {
1667 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1668 if (node->next != NULL) {
1669 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1672 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1680 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1682 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1683 ModestWindowPrivate *parent_priv;
1684 ModestWindowMgr *mgr;
1685 gboolean is_fullscreen;
1686 GtkAction *fs_toggle_action;
1689 mgr = modest_runtime_get_window_mgr ();
1690 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1692 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1694 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1695 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1696 if (is_fullscreen != active)
1697 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1705 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1707 ModestWindowPrivate *parent_priv;
1708 GtkAction *fs_toggle_action;
1711 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1713 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1714 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1715 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1719 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1722 ModestMsgEditWindowPrivate *priv = NULL;
1723 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1725 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1727 gtk_widget_show (priv->cc_caption);
1729 gtk_widget_hide (priv->cc_caption);
1733 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1736 ModestMsgEditWindowPrivate *priv = NULL;
1737 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1739 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1741 gtk_widget_show (priv->bcc_caption);
1743 gtk_widget_hide (priv->bcc_caption);
1747 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1748 ModestRecptEditor *editor)
1750 ModestMsgEditWindowPrivate *priv;
1752 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1753 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1754 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1756 if (editor == NULL) {
1757 GtkWidget *view_focus;
1758 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1760 /* This code should be kept in sync with ModestRecptEditor. The
1761 textview inside the recpt editor is the one that really gets the
1762 focus. As it's inside a scrolled window, and this one inside the
1763 hbox recpt editor inherits from, we'll need to go up in the
1764 hierarchy to know if the text view is part of the recpt editor
1765 or if it's a different text entry */
1767 if (gtk_widget_get_parent (view_focus)) {
1768 GtkWidget *first_parent;
1770 first_parent = gtk_widget_get_parent (view_focus);
1771 if (gtk_widget_get_parent (first_parent) &&
1772 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1773 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1778 editor = MODEST_RECPT_EDITOR (priv->to_field);
1782 modest_address_book_select_addresses (editor);
1787 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1789 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1791 modest_msg_edit_window_open_addressbook (window, NULL);
1795 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1796 gboolean show_toolbar)
1798 ModestWindowPrivate *parent_priv;
1800 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1801 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1803 /* FIXME: we can not just use the code of
1804 modest_msg_edit_window_setup_toolbar because it has a
1805 mixture of both initialization and creation code. */
1808 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1810 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1814 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1815 TnyHeaderFlags priority_flags)
1817 ModestMsgEditWindowPrivate *priv;
1819 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1821 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1822 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1824 if (priv->priority_flags != priority_flags) {
1826 priv->priority_flags = priority_flags;
1828 switch (priority_flags) {
1829 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1830 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1831 gtk_widget_show (priv->priority_icon);
1833 case TNY_HEADER_FLAG_LOW_PRIORITY:
1834 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1835 gtk_widget_show (priv->priority_icon);
1838 gtk_widget_hide (priv->priority_icon);
1845 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1848 ModestMsgEditWindowPrivate *priv;
1849 gint current_format;
1851 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1853 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1855 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1856 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1858 if (current_format != file_format) {
1859 switch (file_format) {
1860 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1861 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1863 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1867 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1868 response = gtk_dialog_run (GTK_DIALOG (dialog));
1869 gtk_widget_destroy (dialog);
1870 if (response == GTK_RESPONSE_OK)
1871 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1875 update_dimmed (window);
1880 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1883 ModestMsgEditWindowPrivate *priv;
1884 WPTextBufferFormat oldfmt, fmt;
1885 gint old_position = 0;
1889 GdkColor *color = NULL;
1890 gboolean bold, bold_set, italic, italic_set;
1891 gboolean underline, underline_set;
1892 gboolean strikethrough, strikethrough_set;
1893 gboolean position_set;
1894 gboolean font_size_set, font_set, color_set;
1897 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1898 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1900 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
1902 /* First we get the currently selected font information */
1903 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
1904 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
1906 switch (oldfmt.text_position) {
1907 case TEXT_POSITION_NORMAL:
1910 case TEXT_POSITION_SUPERSCRIPT:
1918 g_object_set (G_OBJECT (dialog),
1919 "bold", oldfmt.bold != FALSE,
1920 "bold-set", !oldfmt.cs.bold,
1921 "underline", oldfmt.underline != FALSE,
1922 "underline-set", !oldfmt.cs.underline,
1923 "italic", oldfmt.italic != FALSE,
1924 "italic-set", !oldfmt.cs.italic,
1925 "strikethrough", oldfmt.strikethrough != FALSE,
1926 "strikethrough-set", !oldfmt.cs.strikethrough,
1927 "color", &oldfmt.color,
1928 "color-set", !oldfmt.cs.color,
1929 "size", wp_font_size[oldfmt.font_size],
1930 "size-set", !oldfmt.cs.font_size,
1931 "position", old_position,
1932 "position-set", !oldfmt.cs.text_position,
1933 "family", wp_get_font_name (oldfmt.font),
1934 "family-set", !oldfmt.cs.font,
1937 gtk_widget_show_all (dialog);
1938 response = gtk_dialog_run (GTK_DIALOG (dialog));
1939 if (response == GTK_RESPONSE_OK) {
1941 g_object_get( dialog,
1943 "bold-set", &bold_set,
1944 "underline", &underline,
1945 "underline-set", &underline_set,
1947 "italic-set", &italic_set,
1948 "strikethrough", &strikethrough,
1949 "strikethrough-set", &strikethrough_set,
1951 "color-set", &color_set,
1953 "size-set", &font_size_set,
1954 "family", &font_name,
1955 "family-set", &font_set,
1956 "position", &position,
1957 "position-set", &position_set,
1962 if (response == GTK_RESPONSE_OK) {
1963 memset(&fmt, 0, sizeof(fmt));
1969 fmt.italic = italic;
1970 fmt.cs.italic = TRUE;
1972 if (underline_set) {
1973 fmt.underline = underline;
1974 fmt.cs.underline = TRUE;
1976 if (strikethrough_set) {
1977 fmt.strikethrough = strikethrough;
1978 fmt.cs.strikethrough = TRUE;
1983 ? TEXT_POSITION_NORMAL
1984 : ( ( position == 1 )
1985 ? TEXT_POSITION_SUPERSCRIPT
1986 : TEXT_POSITION_SUBSCRIPT );
1987 fmt.cs.text_position = TRUE;
1991 fmt.cs.color = TRUE;
1994 fmt.font = wp_get_font_index(font_name,
1999 if (font_size_set) {
2000 fmt.font_size = wp_get_font_size_index(
2001 font_size, DEFAULT_FONT_SIZE);
2002 fmt.cs.font_size = TRUE;
2004 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2006 gtk_widget_destroy (dialog);
2008 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2012 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2014 ModestMsgEditWindowPrivate *priv;
2016 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2017 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2019 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2021 update_dimmed (window);
2026 update_dimmed (ModestMsgEditWindow *window)
2028 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2029 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2033 gboolean editor_focused;
2035 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2036 editor_focused = gtk_widget_is_focus (priv->msg_body);
2038 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2039 gtk_action_set_sensitive (action, rich_text && editor_focused);
2040 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2041 gtk_action_set_sensitive (action, rich_text && editor_focused);
2042 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2043 gtk_action_set_sensitive (action, rich_text && editor_focused);
2044 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2045 gtk_action_set_sensitive (action, rich_text && editor_focused);
2046 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2047 gtk_action_set_sensitive (action, rich_text && editor_focused);
2048 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2049 gtk_action_set_sensitive (action, rich_text && editor_focused);
2050 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2051 gtk_action_set_sensitive (action, rich_text && editor_focused);
2052 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2053 gtk_action_set_sensitive (action, rich_text && editor_focused);
2054 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2055 gtk_action_set_sensitive (action, rich_text && editor_focused);
2056 widget = priv->font_color_button;
2057 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2058 widget = priv->font_size_toolitem;
2059 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2060 widget = priv->font_face_toolitem;
2061 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2065 setup_insensitive_handlers (ModestMsgEditWindow *window)
2067 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2068 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2071 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2072 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2073 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2074 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2076 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2077 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2078 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2079 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2080 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
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/AlignmentMenu/AlignmentLeftMenu");
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/AlignmentCenterMenu");
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/AlignmentRightMenu");
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/AttachmentsMenu/InsertImageMenu");
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, "/ToolBar/ActionsBold");
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, "/ToolBar/ActionsItalics");
2093 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2094 widget = priv->font_color_button;
2095 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2096 widget = priv->font_size_toolitem;
2097 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2098 widget = priv->font_face_toolitem;
2099 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2104 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2106 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2109 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2110 gtk_action_set_sensitive (action, can_undo);
2114 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2117 GtkTextIter match_start, match_end;
2119 if (image_id == NULL)
2122 gtk_text_buffer_get_start_iter (buffer, &iter);
2124 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2125 GSList *tags = gtk_text_iter_get_tags (&match_start);
2127 for (node = tags; node != NULL; node = g_slist_next (node)) {
2128 GtkTextTag *tag = (GtkTextTag *) node->data;
2129 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2130 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2131 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2133 offset = gtk_text_iter_get_offset (&match_start);
2134 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2135 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2143 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2145 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2146 GtkTextIter real_start, real_end;
2147 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2149 if (gtk_text_iter_compare (start, end) > 0) {
2153 real_start = *start;
2157 GSList *tags = gtk_text_iter_get_tags (&real_start);
2159 for (node = tags; node != NULL; node = g_slist_next (node)) {
2160 GtkTextTag *tag = (GtkTextTag *) node->data;
2161 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2162 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2164 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2166 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2169 } while (gtk_text_iter_forward_char (&real_start)&&
2170 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2174 msg_body_focus (GtkWidget *focus,
2175 GdkEventFocus *event,
2179 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2184 to_field_changed (GtkTextBuffer *buffer,
2185 ModestMsgEditWindow *editor)
2187 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2190 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2191 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2192 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2193 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2197 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2199 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2203 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2205 gboolean rich_text, editor_focused;
2207 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2208 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2209 editor_focused = gtk_widget_is_focus (priv->msg_body);
2212 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2213 else if (!editor_focused)
2214 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2218 reset_modified (ModestMsgEditWindow *editor)
2220 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2221 GtkTextBuffer *buffer;
2223 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2224 gtk_text_buffer_set_modified (buffer, FALSE);
2225 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2226 gtk_text_buffer_set_modified (buffer, FALSE);
2227 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2228 gtk_text_buffer_set_modified (buffer, FALSE);
2229 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2233 is_modified (ModestMsgEditWindow *editor)
2235 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2236 GtkTextBuffer *buffer;
2238 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2239 if (gtk_text_buffer_get_modified (buffer))
2241 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2242 if (gtk_text_buffer_get_modified (buffer))
2244 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2245 if (gtk_text_buffer_get_modified (buffer))
2247 if (gtk_text_buffer_get_modified (priv->text_buffer))
2254 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2256 ModestMsgEditWindowPrivate *priv = NULL;
2258 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2259 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2261 /* check if there's no recipient added */
2262 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2263 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2264 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2265 /* no recipient contents, then select contacts */
2266 modest_msg_edit_window_open_addressbook (window, NULL);
2270 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2272 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2274 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2277 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2284 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2285 ModestMsgEditWindow *window)
2287 modest_msg_edit_window_attach_file (window);
2291 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2293 ModestMsgEditWindow *window)
2295 ModestWindowPrivate *parent_priv;
2300 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2301 selection = gtk_clipboard_wait_for_text (clipboard);
2302 focused = gtk_window_get_focus (GTK_WINDOW (window));
2304 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2305 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2306 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2307 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));