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_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
674 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
675 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
676 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
677 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
679 /* Font size and face placeholder */
680 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
681 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
683 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
684 priv->size_tool_button_label = gtk_label_new (NULL);
685 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
686 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
687 size_text,"</span>", NULL);
688 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
690 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
691 sizes_menu = gtk_menu_new ();
692 priv->size_items_group = NULL;
694 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
695 GtkWidget *size_menu_item;
697 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
698 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
699 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
700 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
701 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
702 gtk_widget_show (size_menu_item);
704 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
708 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
709 GtkWidget *item = (GtkWidget *) node->data;
710 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
714 priv->size_items_group = g_slist_reverse (priv->size_items_group);
715 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
716 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
717 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
718 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
719 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
720 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
721 priv->font_size_toolitem = tool_item;
724 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
725 priv->font_tool_button_label = gtk_label_new (NULL);
726 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
727 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
729 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
730 fonts_menu = gtk_menu_new ();
731 priv->font_items_group = NULL;
733 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
734 GtkWidget *font_menu_item;
735 GtkWidget *child_label;
737 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
738 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
739 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
740 wp_get_font_name (font_index), "</span>", NULL);
741 gtk_label_set_markup (GTK_LABEL (child_label), markup);
744 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
745 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
746 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
747 gtk_widget_show (font_menu_item);
749 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
752 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
753 GtkWidget *item = (GtkWidget *) node->data;
754 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
757 priv->font_items_group = g_slist_reverse (priv->font_items_group);
758 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
759 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
760 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
761 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
762 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
763 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
764 priv->font_face_toolitem = tool_item;
766 /* Set expand and homogeneous for remaining items */
767 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
768 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
769 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
770 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
771 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
772 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
773 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
774 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
775 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
783 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
786 ModestWindowPrivate *parent_priv;
787 ModestMsgEditWindowPrivate *priv;
788 GtkActionGroup *action_group;
789 GError *error = NULL;
790 GdkPixbuf *window_icon = NULL;
793 gboolean prefer_formatted;
796 g_return_val_if_fail (msg, NULL);
798 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
800 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
801 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
803 parent_priv->ui_manager = gtk_ui_manager_new();
804 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
805 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
807 /* Add common actions */
808 gtk_action_group_add_actions (action_group,
809 modest_msg_edit_action_entries,
810 G_N_ELEMENTS (modest_msg_edit_action_entries),
812 gtk_action_group_add_toggle_actions (action_group,
813 modest_msg_edit_toggle_action_entries,
814 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
816 gtk_action_group_add_radio_actions (action_group,
817 modest_msg_edit_alignment_radio_action_entries,
818 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
820 G_CALLBACK (modest_ui_actions_on_change_justify),
822 gtk_action_group_add_radio_actions (action_group,
823 modest_msg_edit_zoom_action_entries,
824 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
826 G_CALLBACK (modest_ui_actions_on_change_zoom),
828 gtk_action_group_add_radio_actions (action_group,
829 modest_msg_edit_priority_action_entries,
830 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
832 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
834 gtk_action_group_add_radio_actions (action_group,
835 modest_msg_edit_file_format_action_entries,
836 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
837 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
838 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
840 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
841 g_object_unref (action_group);
843 /* Load the UI definition */
844 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml", &error);
846 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
847 g_clear_error (&error);
850 /* Add accelerators */
851 gtk_window_add_accel_group (GTK_WINDOW (obj),
852 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
855 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
856 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
859 init_window (MODEST_MSG_EDIT_WINDOW(obj));
861 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
863 gtk_window_set_title (GTK_WINDOW(obj), "Modest");
864 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
866 g_signal_connect (G_OBJECT(obj), "delete-event",
867 G_CALLBACK(on_delete_event), obj);
869 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
871 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
873 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
875 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
877 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
879 /* Set window icon */
880 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
881 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
883 /* Dim at start clipboard actions */
884 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
885 gtk_action_set_sensitive (action, FALSE);
886 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
887 gtk_action_set_sensitive (action, FALSE);
889 /* Setup the file format */
890 conf = modest_runtime_get_conf ();
891 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
893 g_clear_error (&error);
894 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
896 file_format = (prefer_formatted) ?
897 MODEST_FILE_FORMAT_FORMATTED_TEXT :
898 MODEST_FILE_FORMAT_PLAIN_TEXT;
899 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
901 return (ModestWindow*) obj;
905 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
907 GString **string_buffer = (GString **) user_data;
909 *string_buffer = g_string_append (*string_buffer, buffer);
915 * @result: A new string which should be freed with g_free().
918 get_formatted_data (ModestMsgEditWindow *edit_window)
920 ModestMsgEditWindowPrivate *priv;
921 GString *string_buffer = g_string_new ("");
923 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
925 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
927 return g_string_free (string_buffer, FALSE);
932 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
935 const gchar *account_name;
936 ModestMsgEditWindowPrivate *priv;
938 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
940 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
942 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
943 g_return_val_if_fail (account_name, NULL);
946 /* don't free these (except from) */
947 data = g_slice_new0 (MsgData);
948 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
950 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
951 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
952 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
953 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
955 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
957 gtk_text_buffer_get_bounds (buf, &b, &e);
958 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
960 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
961 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
963 data->html_body = NULL;
965 data->attachments = priv->attachments; /* TODO: copy and free ? */
966 data->priority_flags = priv->priority_flags;
971 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
973 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
976 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
984 g_free (data->subject);
985 g_free (data->plain_body);
986 g_free (data->html_body);
988 /* TODO: Free data->attachments? */
990 g_slice_free (MsgData, data);
994 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
997 ModestMsgEditWindowPrivate *priv = NULL;
998 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1000 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1002 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1004 return MODEST_MSG_EDIT_FORMAT_HTML;
1006 return MODEST_MSG_EDIT_FORMAT_TEXT;
1010 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1011 ModestMsgEditFormat format)
1013 ModestMsgEditWindowPrivate *priv;
1015 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1016 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1019 case MODEST_MSG_EDIT_FORMAT_HTML:
1020 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1022 case MODEST_MSG_EDIT_FORMAT_TEXT:
1023 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1026 g_return_if_reached ();
1030 ModestMsgEditFormatState *
1031 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1033 ModestMsgEditFormatState *format_state = NULL;
1034 ModestMsgEditWindowPrivate *priv;
1035 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1037 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1038 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1040 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1042 format_state = g_new0 (ModestMsgEditFormatState, 1);
1043 format_state->bold = buffer_format->bold&0x1;
1044 format_state->italics = buffer_format->italic&0x1;
1045 format_state->bullet = buffer_format->bullet&0x1;
1046 format_state->color = buffer_format->color;
1047 format_state->font_size = buffer_format->font_size;
1048 format_state->font_family = wp_get_font_name (buffer_format->font);
1049 format_state->justification = buffer_format->justification;
1050 g_free (buffer_format);
1052 return format_state;
1057 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1058 const ModestMsgEditFormatState *format_state)
1060 ModestMsgEditWindowPrivate *priv;
1061 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1062 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1063 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1064 g_return_if_fail (format_state != NULL);
1066 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1067 gtk_widget_grab_focus (priv->msg_body);
1068 buffer_format->bold = (format_state->bold != FALSE);
1069 buffer_format->italic = (format_state->italics != FALSE);
1070 buffer_format->color = format_state->color;
1071 buffer_format->font_size = format_state->font_size;
1072 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1073 buffer_format->justification = format_state->justification;
1074 buffer_format->bullet = format_state->bullet;
1076 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1078 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1079 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1080 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1081 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1082 buffer_format->cs.font = (buffer_format->font != current_format->font);
1083 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1084 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1086 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1087 if (buffer_format->cs.bold) {
1088 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1090 if (buffer_format->cs.italic) {
1091 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1093 if (buffer_format->cs.color) {
1094 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1096 if (buffer_format->cs.font_size) {
1097 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1099 if (buffer_format->cs.justification) {
1100 switch (buffer_format->justification) {
1101 case GTK_JUSTIFY_LEFT:
1102 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1104 case GTK_JUSTIFY_CENTER:
1105 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1107 case GTK_JUSTIFY_RIGHT:
1108 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1115 if (buffer_format->cs.font) {
1116 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1118 if (buffer_format->cs.bullet) {
1119 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
1121 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1122 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1124 g_free (current_format);
1129 toggle_action_set_active_block_notify (GtkToggleAction *action,
1132 GSList *proxies = NULL;
1134 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1135 proxies != NULL; proxies = g_slist_next (proxies)) {
1136 GtkWidget *widget = (GtkWidget *) proxies->data;
1137 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1140 gtk_toggle_action_set_active (action, value);
1142 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1143 proxies != NULL; proxies = g_slist_next (proxies)) {
1144 GtkWidget *widget = (GtkWidget *) proxies->data;
1145 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1150 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1152 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1154 ModestWindowPrivate *parent_priv;
1155 ModestMsgEditWindowPrivate *priv;
1156 GtkWidget *new_size_menuitem;
1157 GtkWidget *new_font_menuitem;
1159 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1160 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1162 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1163 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1164 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1165 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1167 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1168 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1169 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1172 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1174 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1175 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1177 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1178 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1180 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1181 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1183 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1184 G_CALLBACK (modest_msg_edit_window_color_button_change),
1186 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1187 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1188 G_CALLBACK (modest_msg_edit_window_color_button_change),
1191 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1192 buffer_format->font_size))->data);
1193 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1197 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1198 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1199 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1201 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1202 G_CALLBACK (modest_msg_edit_window_size_change),
1204 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1205 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1206 G_CALLBACK (modest_msg_edit_window_size_change),
1210 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1211 buffer_format->font))->data);
1212 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1216 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1217 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1218 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1220 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1221 G_CALLBACK (modest_msg_edit_window_font_change),
1223 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1224 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1225 G_CALLBACK (modest_msg_edit_window_font_change),
1229 g_free (buffer_format);
1235 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1238 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1239 ModestMsgEditWindowPrivate *priv;
1240 GtkWidget *dialog = NULL;
1242 const GdkColor *new_color = NULL;
1244 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1245 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1247 #ifdef MODEST_HILDON_VERSION_0
1248 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1249 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1251 dialog = hildon_color_chooser_new ();
1252 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1253 #endif /*MODEST_HILDON_VERSION_0*/
1254 g_free (buffer_format);
1256 response = gtk_dialog_run (GTK_DIALOG (dialog));
1258 case GTK_RESPONSE_OK: {
1259 #ifdef MODEST_HILDON_VERSION_0
1260 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1263 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1265 #endif /*MODEST_HILDON_VERSION_0*/
1272 gtk_widget_destroy (dialog);
1274 if (new_color != NULL)
1275 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1280 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1283 ModestMsgEditWindowPrivate *priv;
1284 GtkWidget *dialog = NULL;
1286 GdkColor *old_color = NULL;
1287 const GdkColor *new_color = NULL;
1289 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1290 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1292 #ifdef MODEST_HILDON_VERSION_0
1293 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1294 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1296 dialog = hildon_color_chooser_new ();
1297 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1298 #endif /*MODEST_HILDON_VERSION_9*/
1300 response = gtk_dialog_run (GTK_DIALOG (dialog));
1302 case GTK_RESPONSE_OK: {
1303 #ifdef MODEST_HILDON_VERSION_0
1304 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1307 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1309 #endif /*MODEST_HILDON_VERSION_0*/
1315 gtk_widget_destroy (dialog);
1317 if (new_color != NULL)
1318 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1323 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1326 ModestMsgEditWindowPrivate *priv;
1327 GtkWidget *dialog = NULL;
1329 gchar *filename = NULL;
1331 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1333 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1335 response = gtk_dialog_run (GTK_DIALOG (dialog));
1337 case GTK_RESPONSE_OK:
1338 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1343 gtk_widget_destroy (dialog);
1346 GdkPixbuf *pixbuf = NULL;
1347 GtkTextIter position;
1348 GtkTextMark *insert_mark;
1350 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1353 GdkPixbufFormat *pixbuf_format;
1355 image_file_id = g_open (filename, O_RDONLY, 0);
1356 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1357 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1358 TnyMimePart *image_part;
1359 TnyStream *image_stream;
1365 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1366 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1367 mime_type = mime_types[0];
1369 mime_type = "image/unknown";
1371 image_part = tny_platform_factory_new_mime_part
1372 (modest_runtime_get_platform_factory ());
1373 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1375 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1376 g_strfreev (mime_types);
1378 content_id = g_strdup_printf ("%d", priv->last_cid);
1379 tny_mime_part_set_content_id (image_part, content_id);
1380 g_free (content_id);
1383 basename = g_path_get_basename (filename);
1384 tny_mime_part_set_filename (image_part, basename);
1387 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1388 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1389 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1390 priv->attachments = g_list_prepend (priv->attachments, image_part);
1391 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1393 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1394 gtk_widget_show_all (priv->attachments_caption);
1395 } else if (image_file_id == -1) {
1396 close (image_file_id);
1405 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1408 ModestMsgEditWindowPrivate *priv;
1409 GtkWidget *dialog = NULL;
1411 gchar *filename = NULL;
1413 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1415 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1417 response = gtk_dialog_run (GTK_DIALOG (dialog));
1419 case GTK_RESPONSE_OK:
1420 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1425 gtk_widget_destroy (dialog);
1430 file_id = g_open (filename, O_RDONLY, 0);
1431 if (file_id != -1) {
1432 TnyMimePart *mime_part;
1434 const gchar *mime_type;
1438 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1439 mime_part = tny_platform_factory_new_mime_part
1440 (modest_runtime_get_platform_factory ());
1441 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1443 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1445 content_id = g_strdup_printf ("%d", priv->last_cid);
1446 tny_mime_part_set_content_id (mime_part, content_id);
1447 g_free (content_id);
1450 basename = g_path_get_basename (filename);
1451 tny_mime_part_set_filename (mime_part, basename);
1454 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1455 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1457 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1458 gtk_widget_show_all (priv->attachments_caption);
1459 } else if (file_id == -1) {
1466 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1469 ModestMsgEditWindowPrivate *priv;
1470 gboolean clean_list = FALSE;
1472 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1473 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1475 if (att_list == NULL) {
1476 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1480 if (att_list == NULL) {
1481 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1483 GtkWidget *confirmation_dialog = NULL;
1484 gboolean dialog_response;
1486 if (att_list->next == NULL) {
1487 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1488 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1489 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1492 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1494 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1495 gtk_widget_destroy (confirmation_dialog);
1496 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1498 for (node = att_list; node != NULL; node = g_list_next (node)) {
1499 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1500 const gchar *att_id;
1501 priv->attachments = g_list_remove (priv->attachments, mime_part);
1503 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1505 att_id = tny_mime_part_get_content_id (mime_part);
1507 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1509 g_object_unref (mime_part);
1514 g_list_free (att_list);
1518 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1521 ModestMsgEditWindowPrivate *priv;
1522 GdkColor *new_color;
1523 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1525 #ifdef MODEST_HILDON_VERSION_0
1526 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1529 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1531 #endif /*MODEST_HILDON_VERSION_0*/
1533 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1535 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1540 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1543 ModestMsgEditWindowPrivate *priv;
1544 gint new_size_index;
1545 ModestMsgEditWindow *window;
1548 window = MODEST_MSG_EDIT_WINDOW (userdata);
1549 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1550 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1552 if (gtk_check_menu_item_get_active (menu_item)) {
1555 label = gtk_bin_get_child (GTK_BIN (menu_item));
1557 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1559 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE,
1560 (gpointer) wp_get_font_size_index (new_size_index, 12)))
1561 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1563 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1564 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1565 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1571 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1574 ModestMsgEditWindowPrivate *priv;
1575 gint new_font_index;
1576 ModestMsgEditWindow *window;
1579 window = MODEST_MSG_EDIT_WINDOW (userdata);
1580 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1581 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1583 if (gtk_check_menu_item_get_active (menu_item)) {
1586 label = gtk_bin_get_child (GTK_BIN (menu_item));
1588 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1590 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1591 (gpointer) new_font_index))
1592 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1594 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1595 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1596 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1602 modest_msg_edit_window_set_zoom (ModestWindow *window,
1605 ModestMsgEditWindowPrivate *priv;
1607 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1609 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1610 priv->zoom_level = zoom;
1611 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1615 modest_msg_edit_window_get_zoom (ModestWindow *window)
1617 ModestMsgEditWindowPrivate *priv;
1619 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1621 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1622 return priv->zoom_level;
1626 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1628 ModestWindowPrivate *parent_priv;
1629 GtkRadioAction *zoom_radio_action;
1630 GSList *group, *node;
1632 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1633 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1634 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1636 group = gtk_radio_action_get_group (zoom_radio_action);
1638 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1639 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1643 for (node = group; node != NULL; node = g_slist_next (node)) {
1644 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1645 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1653 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1655 ModestWindowPrivate *parent_priv;
1656 GtkRadioAction *zoom_radio_action;
1657 GSList *group, *node;
1659 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1660 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1661 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1663 group = gtk_radio_action_get_group (zoom_radio_action);
1665 for (node = group; node != NULL; node = g_slist_next (node)) {
1666 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1667 if (node->next != NULL) {
1668 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1671 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1679 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1681 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1682 ModestWindowPrivate *parent_priv;
1683 ModestWindowMgr *mgr;
1684 gboolean is_fullscreen;
1685 GtkAction *fs_toggle_action;
1688 mgr = modest_runtime_get_window_mgr ();
1689 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1691 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1693 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1694 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1695 if (is_fullscreen != active)
1696 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1704 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1706 ModestWindowPrivate *parent_priv;
1707 GtkAction *fs_toggle_action;
1710 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1712 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1713 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1714 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1718 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1721 ModestMsgEditWindowPrivate *priv = NULL;
1722 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1724 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1726 gtk_widget_show (priv->cc_caption);
1728 gtk_widget_hide (priv->cc_caption);
1732 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1735 ModestMsgEditWindowPrivate *priv = NULL;
1736 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1738 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1740 gtk_widget_show (priv->bcc_caption);
1742 gtk_widget_hide (priv->bcc_caption);
1746 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1747 ModestRecptEditor *editor)
1749 ModestMsgEditWindowPrivate *priv;
1751 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1752 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1753 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1755 if (editor == NULL) {
1756 GtkWidget *view_focus;
1757 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1759 /* This code should be kept in sync with ModestRecptEditor. The
1760 textview inside the recpt editor is the one that really gets the
1761 focus. As it's inside a scrolled window, and this one inside the
1762 hbox recpt editor inherits from, we'll need to go up in the
1763 hierarchy to know if the text view is part of the recpt editor
1764 or if it's a different text entry */
1766 if (gtk_widget_get_parent (view_focus)) {
1767 GtkWidget *first_parent;
1769 first_parent = gtk_widget_get_parent (view_focus);
1770 if (gtk_widget_get_parent (first_parent) &&
1771 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1772 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1777 editor = MODEST_RECPT_EDITOR (priv->to_field);
1781 modest_address_book_select_addresses (editor);
1786 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1788 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1790 modest_msg_edit_window_open_addressbook (window, NULL);
1794 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1795 gboolean show_toolbar)
1797 ModestWindowPrivate *parent_priv;
1799 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1800 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1802 /* FIXME: we can not just use the code of
1803 modest_msg_edit_window_setup_toolbar because it has a
1804 mixture of both initialization and creation code. */
1807 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1809 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1813 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1814 TnyHeaderFlags priority_flags)
1816 ModestMsgEditWindowPrivate *priv;
1818 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1820 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1821 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1823 if (priv->priority_flags != priority_flags) {
1825 priv->priority_flags = priority_flags;
1827 switch (priority_flags) {
1828 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1829 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1830 gtk_widget_show (priv->priority_icon);
1832 case TNY_HEADER_FLAG_LOW_PRIORITY:
1833 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1834 gtk_widget_show (priv->priority_icon);
1837 gtk_widget_hide (priv->priority_icon);
1844 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1847 ModestMsgEditWindowPrivate *priv;
1848 gint current_format;
1850 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1852 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1854 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1855 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1857 if (current_format != file_format) {
1858 switch (file_format) {
1859 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1860 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1862 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1866 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1867 response = gtk_dialog_run (GTK_DIALOG (dialog));
1868 gtk_widget_destroy (dialog);
1869 if (response == GTK_RESPONSE_OK)
1870 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1874 update_dimmed (window);
1879 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1882 ModestMsgEditWindowPrivate *priv;
1883 WPTextBufferFormat oldfmt, fmt;
1884 gint old_position = 0;
1888 GdkColor *color = NULL;
1889 gboolean bold, bold_set, italic, italic_set;
1890 gboolean underline, underline_set;
1891 gboolean strikethrough, strikethrough_set;
1892 gboolean position_set;
1893 gboolean font_size_set, font_set, color_set;
1896 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1897 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1899 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
1901 /* First we get the currently selected font information */
1902 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
1903 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
1905 switch (oldfmt.text_position) {
1906 case TEXT_POSITION_NORMAL:
1909 case TEXT_POSITION_SUPERSCRIPT:
1917 g_object_set (G_OBJECT (dialog),
1918 "bold", oldfmt.bold != FALSE,
1919 "bold-set", !oldfmt.cs.bold,
1920 "underline", oldfmt.underline != FALSE,
1921 "underline-set", !oldfmt.cs.underline,
1922 "italic", oldfmt.italic != FALSE,
1923 "italic-set", !oldfmt.cs.italic,
1924 "strikethrough", oldfmt.strikethrough != FALSE,
1925 "strikethrough-set", !oldfmt.cs.strikethrough,
1926 "color", &oldfmt.color,
1927 "color-set", !oldfmt.cs.color,
1928 "size", wp_font_size[oldfmt.font_size],
1929 "size-set", !oldfmt.cs.font_size,
1930 "position", old_position,
1931 "position-set", !oldfmt.cs.text_position,
1932 "family", wp_get_font_name (oldfmt.font),
1933 "family-set", !oldfmt.cs.font,
1936 gtk_widget_show_all (dialog);
1937 response = gtk_dialog_run (GTK_DIALOG (dialog));
1938 if (response == GTK_RESPONSE_OK) {
1940 g_object_get( dialog,
1942 "bold-set", &bold_set,
1943 "underline", &underline,
1944 "underline-set", &underline_set,
1946 "italic-set", &italic_set,
1947 "strikethrough", &strikethrough,
1948 "strikethrough-set", &strikethrough_set,
1950 "color-set", &color_set,
1952 "size-set", &font_size_set,
1953 "family", &font_name,
1954 "family-set", &font_set,
1955 "position", &position,
1956 "position-set", &position_set,
1961 if (response == GTK_RESPONSE_OK) {
1962 memset(&fmt, 0, sizeof(fmt));
1968 fmt.italic = italic;
1969 fmt.cs.italic = TRUE;
1971 if (underline_set) {
1972 fmt.underline = underline;
1973 fmt.cs.underline = TRUE;
1975 if (strikethrough_set) {
1976 fmt.strikethrough = strikethrough;
1977 fmt.cs.strikethrough = TRUE;
1982 ? TEXT_POSITION_NORMAL
1983 : ( ( position == 1 )
1984 ? TEXT_POSITION_SUPERSCRIPT
1985 : TEXT_POSITION_SUBSCRIPT );
1986 fmt.cs.text_position = TRUE;
1990 fmt.cs.color = TRUE;
1993 fmt.font = wp_get_font_index(font_name,
1998 if (font_size_set) {
1999 fmt.font_size = wp_get_font_size_index(
2000 font_size, DEFAULT_FONT_SIZE);
2001 fmt.cs.font_size = TRUE;
2003 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2005 gtk_widget_destroy (dialog);
2007 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2011 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2013 ModestMsgEditWindowPrivate *priv;
2015 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2016 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2018 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2020 update_dimmed (window);
2025 update_dimmed (ModestMsgEditWindow *window)
2027 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2028 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2032 gboolean editor_focused;
2034 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2035 editor_focused = gtk_widget_is_focus (priv->msg_body);
2037 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2038 gtk_action_set_sensitive (action, rich_text && editor_focused);
2039 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2040 gtk_action_set_sensitive (action, rich_text && editor_focused);
2041 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2042 gtk_action_set_sensitive (action, rich_text && editor_focused);
2043 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2044 gtk_action_set_sensitive (action, rich_text && editor_focused);
2045 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2046 gtk_action_set_sensitive (action, rich_text && editor_focused);
2047 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2048 gtk_action_set_sensitive (action, rich_text && editor_focused);
2049 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2050 gtk_action_set_sensitive (action, rich_text && editor_focused);
2051 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2052 gtk_action_set_sensitive (action, rich_text && editor_focused);
2053 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2054 gtk_action_set_sensitive (action, rich_text && editor_focused);
2055 widget = priv->font_color_button;
2056 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2057 widget = priv->font_size_toolitem;
2058 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2059 widget = priv->font_face_toolitem;
2060 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2064 setup_insensitive_handlers (ModestMsgEditWindow *window)
2066 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2067 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2070 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2071 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2072 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2073 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2075 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2076 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2077 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2078 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2079 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2080 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2081 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2082 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2083 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2084 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2085 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2086 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2087 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2088 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2089 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2090 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2091 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2092 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2093 widget = priv->font_color_button;
2094 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2095 widget = priv->font_size_toolitem;
2096 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2097 widget = priv->font_face_toolitem;
2098 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2103 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2105 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2108 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2109 gtk_action_set_sensitive (action, can_undo);
2113 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2116 GtkTextIter match_start, match_end;
2118 if (image_id == NULL)
2121 gtk_text_buffer_get_start_iter (buffer, &iter);
2123 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2124 GSList *tags = gtk_text_iter_get_tags (&match_start);
2126 for (node = tags; node != NULL; node = g_slist_next (node)) {
2127 GtkTextTag *tag = (GtkTextTag *) node->data;
2128 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2129 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2130 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2132 offset = gtk_text_iter_get_offset (&match_start);
2133 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2134 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2142 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2144 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2145 GtkTextIter real_start, real_end;
2146 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2148 if (gtk_text_iter_compare (start, end) > 0) {
2152 real_start = *start;
2156 GSList *tags = gtk_text_iter_get_tags (&real_start);
2158 for (node = tags; node != NULL; node = g_slist_next (node)) {
2159 GtkTextTag *tag = (GtkTextTag *) node->data;
2160 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2161 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2163 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2165 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2168 } while (gtk_text_iter_forward_char (&real_start)&&
2169 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2173 msg_body_focus (GtkWidget *focus,
2174 GdkEventFocus *event,
2177 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2182 to_field_changed (GtkTextBuffer *buffer,
2183 ModestMsgEditWindow *editor)
2185 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2188 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2189 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2190 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2191 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2195 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2197 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2201 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2203 gboolean rich_text, editor_focused;
2205 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2206 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2207 editor_focused = gtk_widget_is_focus (priv->msg_body);
2210 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2211 else if (!editor_focused)
2212 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2216 reset_modified (ModestMsgEditWindow *editor)
2218 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2219 GtkTextBuffer *buffer;
2221 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2222 gtk_text_buffer_set_modified (buffer, FALSE);
2223 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2224 gtk_text_buffer_set_modified (buffer, FALSE);
2225 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2226 gtk_text_buffer_set_modified (buffer, FALSE);
2227 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2231 is_modified (ModestMsgEditWindow *editor)
2233 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2234 GtkTextBuffer *buffer;
2236 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2237 if (gtk_text_buffer_get_modified (buffer))
2239 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2240 if (gtk_text_buffer_get_modified (buffer))
2242 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2243 if (gtk_text_buffer_get_modified (buffer))
2245 if (gtk_text_buffer_get_modified (priv->text_buffer))
2252 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2254 ModestMsgEditWindowPrivate *priv = NULL;
2256 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2257 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2259 /* check if there's no recipient added */
2260 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2261 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2262 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2263 /* no recipient contents, then select contacts */
2264 modest_msg_edit_window_open_addressbook (window, NULL);
2268 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2270 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2272 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2275 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2282 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2283 ModestMsgEditWindow *window)
2285 modest_msg_edit_window_attach_file (window);
2289 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2291 ModestMsgEditWindow *window)
2293 ModestWindowPrivate *parent_priv;
2298 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2299 selection = gtk_clipboard_wait_for_text (clipboard);
2300 focused = gtk_window_get_focus (GTK_WINDOW (window));
2302 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2303 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2304 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2305 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));