1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include <glib/gi18n.h>
33 #include <glib/gstdio.h>
35 #include <tny-account-store.h>
36 #include <tny-fs-stream.h>
37 #include <tny-vfs-stream.h>
41 #include <modest-account-mgr.h>
42 #include <modest-account-mgr-helpers.h>
44 #include <widgets/modest-msg-edit-window.h>
45 #include <widgets/modest-combo-box.h>
46 #include <widgets/modest-recpt-editor.h>
47 #include <widgets/modest-attachments-view.h>
49 #include <modest-runtime.h>
51 #include "modest-platform.h"
52 #include "modest-icon-names.h"
53 #include "modest-widget-memory.h"
54 #include "modest-window-priv.h"
55 #include "modest-mail-operation.h"
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-address-book.h"
59 #include "modest-text-utils.h"
60 #include <tny-simple-list.h>
61 #include <wptextview.h>
62 #include <wptextbuffer.h>
63 #include "modest-scroll-area.h"
65 #include "modest-hildon-includes.h"
66 #include "widgets/modest-msg-edit-window-ui.h"
67 #include <libgnomevfs/gnome-vfs-mime.h>
70 #define DEFAULT_FONT_SIZE 3
71 #define DEFAULT_FONT 2
72 #define DEFAULT_SIZE_BUTTON_FONT_FAMILY "Sans"
73 #define DEFAULT_SIZE_COMBOBOX_WIDTH 80
74 #define DEFAULT_MAIN_VBOX_SPACING 6
75 #define SUBJECT_MAX_LENGTH 1000
77 static void modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass);
78 static void modest_msg_edit_window_init (ModestMsgEditWindow *obj);
79 static void modest_msg_edit_window_finalize (GObject *obj);
81 static gboolean msg_body_focus (GtkWidget *focus, GdkEventFocus *event, gpointer userdata);
82 static void recpt_field_changed (GtkTextBuffer *buffer, ModestMsgEditWindow *editor);
83 static void send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
84 static void style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor);
85 static void setup_insensitive_handlers (ModestMsgEditWindow *editor);
86 static void reset_modified (ModestMsgEditWindow *editor);
87 static gboolean is_modified (ModestMsgEditWindow *editor);
89 static void text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window);
90 static void text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata);
91 static void text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window);
92 static void text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id);
93 static void subject_field_changed (GtkEditable *editable, ModestMsgEditWindow *window);
94 static void modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
96 static void modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
98 static void modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
100 static void modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window);
101 static gboolean modest_msg_edit_window_window_state_event (GtkWidget *widget,
102 GdkEventWindowState *event,
104 static void modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
105 ModestRecptEditor *editor);
106 static void modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
107 ModestMsgEditWindow *window);
109 /* ModestWindow methods implementation */
110 static void modest_msg_edit_window_set_zoom (ModestWindow *window, gdouble zoom);
111 static gdouble modest_msg_edit_window_get_zoom (ModestWindow *window);
112 static gboolean modest_msg_edit_window_zoom_minus (ModestWindow *window);
113 static gboolean modest_msg_edit_window_zoom_plus (ModestWindow *window);
114 static void modest_msg_edit_window_show_toolbar (ModestWindow *window,
115 gboolean show_toolbar);
116 static void modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
118 ModestMsgEditWindow *window);
119 static void update_window_title (ModestMsgEditWindow *window);
120 static void update_dimmed (ModestMsgEditWindow *window);
123 /* list my signals */
130 typedef struct _ModestMsgEditWindowPrivate ModestMsgEditWindowPrivate;
131 struct _ModestMsgEditWindowPrivate {
133 GtkWidget *header_box;
135 ModestPairList *from_field_protos;
136 GtkWidget *from_field;
140 GtkWidget *bcc_field;
141 GtkWidget *subject_field;
142 GtkWidget *attachments_view;
143 GtkWidget *priority_icon;
144 GtkWidget *add_attachment_button;
146 GtkWidget *cc_caption;
147 GtkWidget *bcc_caption;
148 GtkWidget *attachments_caption;
150 GtkTextBuffer *text_buffer;
152 GtkWidget *font_size_toolitem;
153 GtkWidget *font_face_toolitem;
154 GtkWidget *font_color_button;
155 GSList *font_items_group;
156 GtkWidget *font_tool_button_label;
157 GSList *size_items_group;
158 GtkWidget *size_tool_button_label;
165 TnyHeaderFlags priority_flags;
169 gulong clipboard_change_handler_id;
174 #define MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
175 MODEST_TYPE_MSG_EDIT_WINDOW, \
176 ModestMsgEditWindowPrivate))
178 static GtkWindowClass *parent_class = NULL;
180 /* uncomment the following if you have defined any signals */
181 /* static guint signals[LAST_SIGNAL] = {0}; */
184 modest_msg_edit_window_get_type (void)
186 static GType my_type = 0;
188 static const GTypeInfo my_info = {
189 sizeof(ModestMsgEditWindowClass),
190 NULL, /* base init */
191 NULL, /* base finalize */
192 (GClassInitFunc) modest_msg_edit_window_class_init,
193 NULL, /* class finalize */
194 NULL, /* class data */
195 sizeof(ModestMsgEditWindow),
197 (GInstanceInitFunc) modest_msg_edit_window_init,
200 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
201 "ModestMsgEditWindow",
204 wp_text_buffer_library_init ();
210 save_state (ModestWindow *self)
212 modest_widget_memory_save (modest_runtime_get_conf(),
213 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
218 restore_settings (ModestMsgEditWindow *self)
220 modest_widget_memory_restore (modest_runtime_get_conf(),
221 G_OBJECT(self), MODEST_CONF_EDIT_WINDOW_KEY);
226 modest_msg_edit_window_class_init (ModestMsgEditWindowClass *klass)
228 GObjectClass *gobject_class;
229 ModestWindowClass *modest_window_class;
230 gobject_class = (GObjectClass*) klass;
231 modest_window_class = (ModestWindowClass*) klass;
233 parent_class = g_type_class_peek_parent (klass);
234 gobject_class->finalize = modest_msg_edit_window_finalize;
236 modest_window_class->set_zoom_func = modest_msg_edit_window_set_zoom;
237 modest_window_class->get_zoom_func = modest_msg_edit_window_get_zoom;
238 modest_window_class->zoom_plus_func = modest_msg_edit_window_zoom_plus;
239 modest_window_class->zoom_minus_func = modest_msg_edit_window_zoom_minus;
240 modest_window_class->show_toolbar_func = modest_msg_edit_window_show_toolbar;
242 g_type_class_add_private (gobject_class, sizeof(ModestMsgEditWindowPrivate));
244 modest_window_class->save_state_func = save_state;
248 modest_msg_edit_window_init (ModestMsgEditWindow *obj)
250 ModestMsgEditWindowPrivate *priv;
251 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
253 priv->msg_body = NULL;
254 priv->from_field = NULL;
255 priv->to_field = NULL;
256 priv->cc_field = NULL;
257 priv->bcc_field = NULL;
258 priv->subject_field = NULL;
259 priv->attachments = NULL;
261 priv->zoom_level = 1.0;
263 priv->cc_caption = NULL;
264 priv->bcc_caption = NULL;
266 priv->priority_flags = 0;
268 priv->draft_msg = NULL;
269 priv->clipboard_change_handler_id = 0;
273 /* FIXME: this is a dup from the one in gtk/ */
276 * @result: A ModestPairList, which must be freed with modest_pair_list_free().
278 static ModestPairList*
279 get_transports (void)
281 GSList *transports = NULL;
283 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
284 GSList *accounts = modest_account_mgr_account_names (account_mgr,
285 TRUE /* only enabled accounts. */);
287 GSList *cursor = accounts;
289 const gchar *account_name = cursor->data;
290 gchar *from_string = NULL;
292 from_string = modest_account_mgr_get_from_string (account_mgr,
296 if (from_string && account_name) {
297 gchar *name = g_strdup (account_name);
298 ModestPair *pair = modest_pair_new ((gpointer) name,
299 (gpointer) from_string , TRUE);
300 transports = g_slist_prepend (transports, pair);
303 cursor = cursor->next;
305 g_slist_free (accounts);
311 init_window (ModestMsgEditWindow *obj)
313 GtkWidget *from_caption, *to_caption, *subject_caption;
314 GtkWidget *main_vbox;
315 ModestMsgEditWindowPrivate *priv;
317 GtkSizeGroup *size_group;
319 GtkWidget *scroll_area;
320 GtkWidget *subject_box;
321 GtkWidget *attachment_icon;
323 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE(obj);
325 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
327 /* Note: This ModestPairList* must exist for as long as the combo
328 * that uses it, because the ModestComboBox uses the ID opaquely,
329 * so it can't know how to manage its memory. */
330 priv->from_field_protos = get_transports ();
332 priv->from_field = modest_combo_box_new (priv->from_field_protos, g_str_equal);
334 priv->to_field = modest_recpt_editor_new ();
335 priv->cc_field = modest_recpt_editor_new ();
336 priv->bcc_field = modest_recpt_editor_new ();
337 subject_box = gtk_hbox_new (FALSE, 0);
338 priv->priority_icon = gtk_image_new ();
339 gtk_box_pack_start (GTK_BOX (subject_box), priv->priority_icon, FALSE, FALSE, 0);
340 priv->subject_field = gtk_entry_new_with_max_length (SUBJECT_MAX_LENGTH);
341 g_object_set (G_OBJECT (priv->subject_field), "hildon-input-mode", HILDON_GTK_INPUT_MODE_FULL, NULL);
342 gtk_box_pack_start (GTK_BOX (subject_box), priv->subject_field, TRUE, TRUE, 0);
343 priv->add_attachment_button = gtk_button_new ();
344 GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (priv->add_attachment_button), GTK_CAN_FOCUS);
345 gtk_button_set_relief (GTK_BUTTON (priv->add_attachment_button), GTK_RELIEF_NONE);
346 gtk_button_set_focus_on_click (GTK_BUTTON (priv->add_attachment_button), FALSE);
347 gtk_button_set_alignment (GTK_BUTTON (priv->add_attachment_button), 1.0, 1.0);
348 attachment_icon = gtk_image_new_from_icon_name (MODEST_HEADER_ICON_ATTACH, GTK_ICON_SIZE_BUTTON);
349 gtk_container_add (GTK_CONTAINER (priv->add_attachment_button), attachment_icon);
350 gtk_box_pack_start (GTK_BOX (subject_box), priv->add_attachment_button, FALSE, FALSE, 0);
351 priv->attachments_view = modest_attachments_view_new (NULL);
353 priv->header_box = gtk_vbox_new (FALSE, 0);
355 from_caption = hildon_caption_new (size_group, _("mail_va_from"), priv->from_field, NULL, 0);
356 to_caption = hildon_caption_new (size_group, _("mail_va_to"), priv->to_field, NULL, 0);
357 priv->cc_caption = hildon_caption_new (size_group, _("mail_va_cc"), priv->cc_field, NULL, 0);
358 priv->bcc_caption = hildon_caption_new (size_group, _("mail_va_hotfix1"), priv->bcc_field, NULL, 0);
359 subject_caption = hildon_caption_new (size_group, _("mail_va_subject"), subject_box, NULL, 0);
360 priv->attachments_caption = hildon_caption_new (size_group, _("mail_va_attachment"), priv->attachments_view, NULL, 0);
361 g_object_unref (size_group);
363 size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
364 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->to_field), size_group);
365 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->cc_field), size_group);
366 modest_recpt_editor_set_field_size_group (MODEST_RECPT_EDITOR (priv->bcc_field), size_group);
367 gtk_size_group_add_widget (size_group, priv->subject_field);
368 gtk_size_group_add_widget (size_group, priv->attachments_view);
369 g_object_unref (size_group);
371 gtk_box_pack_start (GTK_BOX (priv->header_box), from_caption, FALSE, FALSE, 0);
372 gtk_box_pack_start (GTK_BOX (priv->header_box), to_caption, FALSE, FALSE, 0);
373 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->cc_caption, FALSE, FALSE, 0);
374 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->bcc_caption, FALSE, FALSE, 0);
375 gtk_box_pack_start (GTK_BOX (priv->header_box), subject_caption, FALSE, FALSE, 0);
376 gtk_box_pack_start (GTK_BOX (priv->header_box), priv->attachments_caption, FALSE, FALSE, 0);
377 gtk_widget_set_no_show_all (priv->attachments_caption, TRUE);
380 priv->msg_body = wp_text_view_new ();
381 gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (priv->msg_body), GTK_WRAP_WORD_CHAR);
382 priv->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
383 g_object_set (priv->text_buffer, "font_scale", 1.0, NULL);
384 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
385 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
386 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
388 g_signal_connect (G_OBJECT (priv->text_buffer), "refresh_attributes",
389 G_CALLBACK (text_buffer_refresh_attributes), obj);
390 g_signal_connect (G_OBJECT (priv->text_buffer), "delete-range",
391 G_CALLBACK (text_buffer_delete_range), obj);
392 g_signal_connect (G_OBJECT (priv->text_buffer), "can-undo",
393 G_CALLBACK (text_buffer_can_undo), obj);
394 g_signal_connect (G_OBJECT (obj), "window-state-event",
395 G_CALLBACK (modest_msg_edit_window_window_state_event),
397 g_signal_connect_swapped (G_OBJECT (priv->to_field), "open-addressbook",
398 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
399 g_signal_connect_swapped (G_OBJECT (priv->cc_field), "open-addressbook",
400 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
401 g_signal_connect_swapped (G_OBJECT (priv->bcc_field), "open-addressbook",
402 G_CALLBACK (modest_msg_edit_window_open_addressbook), obj);
404 g_signal_connect (G_OBJECT (priv->add_attachment_button), "clicked",
405 G_CALLBACK (modest_msg_edit_window_add_attachment_clicked), obj);
407 g_signal_connect (G_OBJECT (priv->msg_body), "focus-in-event",
408 G_CALLBACK (msg_body_focus), obj);
409 g_signal_connect (G_OBJECT (priv->msg_body), "focus-out-event",
410 G_CALLBACK (msg_body_focus), obj);
411 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))),
412 "changed", G_CALLBACK (recpt_field_changed), obj);
413 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))),
414 "changed", G_CALLBACK (recpt_field_changed), obj);
415 g_signal_connect (G_OBJECT (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))),
416 "changed", G_CALLBACK (recpt_field_changed), obj);
417 recpt_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
418 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
420 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
421 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
422 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
424 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
426 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
427 frame = gtk_frame_new (NULL);
428 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
430 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
431 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
432 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
434 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
435 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
436 gtk_widget_hide (priv->cc_caption);
438 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
439 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
440 gtk_widget_hide (priv->bcc_caption);
443 gtk_container_add (GTK_CONTAINER(obj), priv->scroll);
444 scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
445 gtk_container_add (GTK_CONTAINER (frame), scroll_area);
446 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
447 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
449 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
450 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
456 modest_msg_edit_window_finalize (GObject *obj)
458 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
461 if (priv->clipboard_change_handler_id > 0) {
462 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
463 priv->clipboard_change_handler_id = 0;
466 /* This had to stay alive for as long as the combobox that used it: */
467 modest_pair_list_free (priv->from_field_protos);
469 G_OBJECT_CLASS(parent_class)->finalize (obj);
473 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
475 GtkWidget *close_dialog;
476 ModestMsgEditWindowPrivate *priv;
479 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
480 modest_window_save_state (MODEST_WINDOW (self));
481 if (is_modified (self)) {
482 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
483 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
484 gtk_widget_destroy (close_dialog);
486 if (response != GTK_RESPONSE_CANCEL) {
487 modest_ui_actions_on_save_to_drafts (NULL, self);
490 /* /\* remove old message from drafts *\/ */
491 /* if (priv->draft_msg) { */
492 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
493 /* TnyAccount *account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(), */
495 /* TNY_ACCOUNT_TYPE_STORE); */
496 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
497 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
498 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
499 /* tny_folder_remove_msg (folder, header, NULL); */
500 /* g_object_unref (folder); */
501 /* g_object_unref (header); */
502 /* g_object_unref (priv->draft_msg); */
503 /* priv->draft_msg = NULL; */
505 gtk_widget_destroy (GTK_WIDGET (self));
511 menubar_to_menu (GtkUIManager *ui_manager)
513 GtkWidget *main_menu;
517 /* Create new main menu */
518 main_menu = gtk_menu_new();
520 /* Get the menubar from the UI manager */
521 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
523 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
527 menu = GTK_WIDGET (iter->data);
528 gtk_widget_reparent(menu, main_menu);
530 iter = g_list_next (iter);
537 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
540 const gchar *to, *cc, *bcc, *subject;
542 ModestMsgEditWindowPrivate *priv;
545 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
546 g_return_if_fail (TNY_IS_MSG (msg));
548 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
550 header = tny_msg_get_header (msg);
551 to = tny_header_get_to (header);
552 cc = tny_header_get_cc (header);
553 bcc = tny_header_get_bcc (header);
554 subject = tny_header_get_subject (header);
557 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
559 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
561 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
563 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
565 update_window_title (self);
567 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
568 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
569 body = modest_tny_msg_get_body (msg, TRUE);
571 if ((body == NULL)||(body[0] == '\0')) {
573 body = modest_text_utils_convert_to_html ("");
575 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
576 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
579 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
582 /* Get the default format required from configuration */
583 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
584 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
587 /* Set the default focus depending on having already a To: field or not */
588 if ((!to)||(*to == '\0')) {
589 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
591 gtk_widget_grab_focus (priv->msg_body);
594 /* TODO: lower priority, select in the From: combo to the
595 value that comes from msg <- not sure, should it be
598 /* Add attachments to the view */
599 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
600 if (priv->attachments == NULL)
601 gtk_widget_hide_all (priv->attachments_caption);
603 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
604 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
606 reset_modified (self);
608 update_dimmed (self);
609 text_buffer_can_undo (priv->text_buffer, FALSE, self);
611 priv->draft_msg = msg;
615 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
618 GList *item_children, *node;
619 GtkWidget *bin_child;
621 bin_child = gtk_bin_get_child (GTK_BIN(item));
623 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
625 for (node = item_children; node != NULL; node = g_list_next (node)) {
626 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
627 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
630 g_list_free (item_children);
634 menu_tool_button_dont_expand (GtkMenuToolButton *item)
637 GList *item_children, *node;
639 box = gtk_bin_get_child (GTK_BIN (item));
640 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
641 item_children = gtk_container_get_children (GTK_CONTAINER (box));
643 for (node = item_children; node != NULL; node = g_list_next (node)) {
644 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
645 if (GTK_IS_TOGGLE_BUTTON (node->data))
646 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
647 else if (GTK_IS_BUTTON (node->data))
648 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
650 g_list_free (item_children);
655 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
657 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
658 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
659 GtkWidget *placeholder;
660 GtkWidget *tool_item;
665 GtkWidget *sizes_menu;
666 GtkWidget *fonts_menu;
667 GSList *radio_group = NULL;
672 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
673 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
675 /* should we hide the toolbar? */
676 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
677 gtk_widget_hide (parent_priv->toolbar);
679 /* Font color placeholder */
680 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
681 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
684 tool_item = GTK_WIDGET (gtk_tool_item_new ());
685 priv->font_color_button = hildon_color_button_new ();
686 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
687 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
688 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
689 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
690 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
691 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
692 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
694 /* Font size and face placeholder */
695 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
696 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
698 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
699 priv->size_tool_button_label = gtk_label_new (NULL);
700 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
701 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
702 size_text,"</span>", NULL);
703 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
705 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
706 sizes_menu = gtk_menu_new ();
707 priv->size_items_group = NULL;
709 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
710 GtkWidget *size_menu_item;
712 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
713 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
714 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
715 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
716 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
717 gtk_widget_show (size_menu_item);
719 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
723 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
724 GtkWidget *item = (GtkWidget *) node->data;
725 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
729 priv->size_items_group = g_slist_reverse (priv->size_items_group);
730 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
731 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
732 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
733 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
734 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
735 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
736 priv->font_size_toolitem = tool_item;
739 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
740 priv->font_tool_button_label = gtk_label_new (NULL);
741 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
742 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
744 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
745 fonts_menu = gtk_menu_new ();
746 priv->font_items_group = NULL;
748 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
749 GtkWidget *font_menu_item;
750 GtkWidget *child_label;
752 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
753 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
754 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
755 wp_get_font_name (font_index), "</span>", NULL);
756 gtk_label_set_markup (GTK_LABEL (child_label), markup);
759 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
760 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
761 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
762 gtk_widget_show (font_menu_item);
764 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
767 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
768 GtkWidget *item = (GtkWidget *) node->data;
769 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
772 priv->font_items_group = g_slist_reverse (priv->font_items_group);
773 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
774 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
775 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
776 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
777 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
778 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
779 priv->font_face_toolitem = tool_item;
781 /* Set expand and homogeneous for remaining items */
782 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
783 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
784 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
785 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
786 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
787 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
788 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
789 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
790 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
798 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
801 ModestWindowPrivate *parent_priv;
802 ModestMsgEditWindowPrivate *priv;
803 GtkActionGroup *action_group;
804 GError *error = NULL;
805 GdkPixbuf *window_icon = NULL;
808 gboolean prefer_formatted;
811 g_return_val_if_fail (msg, NULL);
813 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
815 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
816 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
818 parent_priv->ui_manager = gtk_ui_manager_new();
819 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
820 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
822 /* Add common actions */
823 gtk_action_group_add_actions (action_group,
824 modest_msg_edit_action_entries,
825 G_N_ELEMENTS (modest_msg_edit_action_entries),
827 gtk_action_group_add_toggle_actions (action_group,
828 modest_msg_edit_toggle_action_entries,
829 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
831 gtk_action_group_add_radio_actions (action_group,
832 modest_msg_edit_alignment_radio_action_entries,
833 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
835 G_CALLBACK (modest_ui_actions_on_change_justify),
837 gtk_action_group_add_radio_actions (action_group,
838 modest_msg_edit_zoom_action_entries,
839 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
841 G_CALLBACK (modest_ui_actions_on_change_zoom),
843 gtk_action_group_add_radio_actions (action_group,
844 modest_msg_edit_priority_action_entries,
845 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
847 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
849 gtk_action_group_add_radio_actions (action_group,
850 modest_msg_edit_file_format_action_entries,
851 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
852 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
853 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
855 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
856 g_object_unref (action_group);
858 /* Load the UI definition */
859 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml", &error);
861 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
862 g_clear_error (&error);
865 /* Add accelerators */
866 gtk_window_add_accel_group (GTK_WINDOW (obj),
867 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
870 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
871 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
874 init_window (MODEST_MSG_EDIT_WINDOW(obj));
876 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
878 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
880 g_signal_connect (G_OBJECT(obj), "delete-event",
881 G_CALLBACK(on_delete_event), obj);
883 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
885 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
887 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
889 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
891 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
893 /* Set window icon */
894 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
895 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
897 /* Dim at start clipboard actions */
898 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
899 gtk_action_set_sensitive (action, FALSE);
900 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
901 gtk_action_set_sensitive (action, FALSE);
903 /* set initial state of cc and bcc */
904 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
905 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
906 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
907 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
908 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
909 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
911 /* Setup the file format */
912 conf = modest_runtime_get_conf ();
913 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
915 g_clear_error (&error);
916 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
918 file_format = (prefer_formatted) ?
919 MODEST_FILE_FORMAT_FORMATTED_TEXT :
920 MODEST_FILE_FORMAT_PLAIN_TEXT;
921 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
923 return (ModestWindow*) obj;
927 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
929 GString **string_buffer = (GString **) user_data;
931 *string_buffer = g_string_append (*string_buffer, buffer);
937 * @result: A new string which should be freed with g_free().
940 get_formatted_data (ModestMsgEditWindow *edit_window)
942 ModestMsgEditWindowPrivate *priv;
943 GString *string_buffer = g_string_new ("");
945 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
947 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
949 return g_string_free (string_buffer, FALSE);
954 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
957 const gchar *account_name;
958 ModestMsgEditWindowPrivate *priv;
960 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
962 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
964 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
965 g_return_val_if_fail (account_name, NULL);
968 /* don't free these (except from) */
969 data = g_slice_new0 (MsgData);
970 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
972 data->account_name = g_strdup (account_name);
973 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
974 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
975 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
976 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
977 if (priv->draft_msg) {
978 data->draft_msg = g_object_ref (priv->draft_msg);
980 data->draft_msg = NULL;
983 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
985 gtk_text_buffer_get_bounds (buf, &b, &e);
986 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
988 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
989 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
991 data->html_body = NULL;
993 data->attachments = priv->attachments; /* TODO: copy and free ? */
994 data->priority_flags = priv->priority_flags;
999 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
1001 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1004 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1012 g_free (data->subject);
1013 g_free (data->plain_body);
1014 g_free (data->html_body);
1015 if (data->draft_msg != NULL) {
1016 g_object_unref (data->draft_msg);
1017 data->draft_msg = NULL;
1019 g_free (data->account_name);
1021 /* TODO: Free data->attachments? */
1023 g_slice_free (MsgData, data);
1027 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1030 ModestMsgEditWindowPrivate *priv = NULL;
1031 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1033 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1035 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1037 return MODEST_MSG_EDIT_FORMAT_HTML;
1039 return MODEST_MSG_EDIT_FORMAT_TEXT;
1043 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1044 ModestMsgEditFormat format)
1046 ModestMsgEditWindowPrivate *priv;
1048 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1049 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1052 case MODEST_MSG_EDIT_FORMAT_HTML:
1053 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1055 case MODEST_MSG_EDIT_FORMAT_TEXT:
1056 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1059 g_return_if_reached ();
1063 ModestMsgEditFormatState *
1064 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1066 ModestMsgEditFormatState *format_state = NULL;
1067 ModestMsgEditWindowPrivate *priv;
1068 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1070 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1071 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1073 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1075 format_state = g_new0 (ModestMsgEditFormatState, 1);
1076 format_state->bold = buffer_format->bold&0x1;
1077 format_state->italics = buffer_format->italic&0x1;
1078 format_state->bullet = buffer_format->bullet&0x1;
1079 format_state->color = buffer_format->color;
1080 format_state->font_size = buffer_format->font_size;
1081 format_state->font_family = wp_get_font_name (buffer_format->font);
1082 format_state->justification = buffer_format->justification;
1083 g_free (buffer_format);
1085 return format_state;
1090 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1091 const ModestMsgEditFormatState *format_state)
1093 ModestMsgEditWindowPrivate *priv;
1094 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1095 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1096 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1097 g_return_if_fail (format_state != NULL);
1099 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1100 gtk_widget_grab_focus (priv->msg_body);
1101 buffer_format->bold = (format_state->bold != FALSE);
1102 buffer_format->italic = (format_state->italics != FALSE);
1103 buffer_format->color = format_state->color;
1104 buffer_format->font_size = format_state->font_size;
1105 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1106 buffer_format->justification = format_state->justification;
1107 buffer_format->bullet = format_state->bullet;
1109 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1111 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1112 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1113 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1114 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1115 buffer_format->cs.font = (buffer_format->font != current_format->font);
1116 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1117 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1119 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1120 if (buffer_format->cs.bold) {
1121 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1123 if (buffer_format->cs.italic) {
1124 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1126 if (buffer_format->cs.color) {
1127 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1129 if (buffer_format->cs.font_size) {
1130 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1132 if (buffer_format->cs.justification) {
1133 switch (buffer_format->justification) {
1134 case GTK_JUSTIFY_LEFT:
1135 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1137 case GTK_JUSTIFY_CENTER:
1138 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1140 case GTK_JUSTIFY_RIGHT:
1141 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1148 if (buffer_format->cs.font) {
1149 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1151 if (buffer_format->cs.bullet) {
1152 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
1154 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1155 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1157 g_free (current_format);
1162 toggle_action_set_active_block_notify (GtkToggleAction *action,
1165 GSList *proxies = NULL;
1167 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1168 proxies != NULL; proxies = g_slist_next (proxies)) {
1169 GtkWidget *widget = (GtkWidget *) proxies->data;
1170 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1173 gtk_toggle_action_set_active (action, value);
1175 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1176 proxies != NULL; proxies = g_slist_next (proxies)) {
1177 GtkWidget *widget = (GtkWidget *) proxies->data;
1178 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1183 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1185 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1187 ModestWindowPrivate *parent_priv;
1188 ModestMsgEditWindowPrivate *priv;
1189 GtkWidget *new_size_menuitem;
1190 GtkWidget *new_font_menuitem;
1192 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1193 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1195 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1196 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1197 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1198 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1200 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1201 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1202 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1205 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1207 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1208 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1210 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1211 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1213 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1214 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1216 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1217 G_CALLBACK (modest_msg_edit_window_color_button_change),
1219 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1220 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1221 G_CALLBACK (modest_msg_edit_window_color_button_change),
1224 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1225 buffer_format->font_size))->data);
1226 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1230 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1231 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1232 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1234 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1235 G_CALLBACK (modest_msg_edit_window_size_change),
1237 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1238 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1239 G_CALLBACK (modest_msg_edit_window_size_change),
1243 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1244 buffer_format->font))->data);
1245 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1249 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1250 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1251 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1253 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1254 G_CALLBACK (modest_msg_edit_window_font_change),
1256 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1257 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1258 G_CALLBACK (modest_msg_edit_window_font_change),
1262 g_free (buffer_format);
1268 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1271 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1272 ModestMsgEditWindowPrivate *priv;
1273 GtkWidget *dialog = NULL;
1275 const GdkColor *new_color = NULL;
1277 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1278 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1280 #ifdef MODEST_HILDON_VERSION_0
1281 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1282 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1284 dialog = hildon_color_chooser_new ();
1285 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1286 #endif /*MODEST_HILDON_VERSION_0*/
1287 g_free (buffer_format);
1289 response = gtk_dialog_run (GTK_DIALOG (dialog));
1291 case GTK_RESPONSE_OK: {
1292 #ifdef MODEST_HILDON_VERSION_0
1293 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1296 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1298 #endif /*MODEST_HILDON_VERSION_0*/
1305 gtk_widget_destroy (dialog);
1307 if (new_color != NULL)
1308 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1313 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1316 ModestMsgEditWindowPrivate *priv;
1317 GtkWidget *dialog = NULL;
1319 GdkColor *old_color = NULL;
1320 const GdkColor *new_color = NULL;
1322 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1323 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1325 #ifdef MODEST_HILDON_VERSION_0
1326 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1327 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1329 dialog = hildon_color_chooser_new ();
1330 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1331 #endif /*MODEST_HILDON_VERSION_9*/
1333 response = gtk_dialog_run (GTK_DIALOG (dialog));
1335 case GTK_RESPONSE_OK: {
1336 #ifdef MODEST_HILDON_VERSION_0
1337 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1340 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1342 #endif /*MODEST_HILDON_VERSION_0*/
1348 gtk_widget_destroy (dialog);
1350 if (new_color != NULL)
1351 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1356 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1359 ModestMsgEditWindowPrivate *priv;
1360 GtkWidget *dialog = NULL;
1362 gchar *filename = NULL;
1364 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1366 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1368 response = gtk_dialog_run (GTK_DIALOG (dialog));
1370 case GTK_RESPONSE_OK:
1371 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1376 gtk_widget_destroy (dialog);
1379 GdkPixbuf *pixbuf = NULL;
1380 GtkTextIter position;
1381 GtkTextMark *insert_mark;
1383 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1386 GdkPixbufFormat *pixbuf_format;
1388 image_file_id = g_open (filename, O_RDONLY, 0);
1389 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1390 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1391 TnyMimePart *image_part;
1392 TnyStream *image_stream;
1398 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1399 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1400 mime_type = mime_types[0];
1402 mime_type = "image/unknown";
1404 image_part = tny_platform_factory_new_mime_part
1405 (modest_runtime_get_platform_factory ());
1406 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1408 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1409 g_strfreev (mime_types);
1411 content_id = g_strdup_printf ("%d", priv->last_cid);
1412 tny_mime_part_set_content_id (image_part, content_id);
1413 g_free (content_id);
1416 basename = g_path_get_basename (filename);
1417 tny_mime_part_set_filename (image_part, basename);
1420 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1421 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1422 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1423 priv->attachments = g_list_prepend (priv->attachments, image_part);
1424 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1426 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1427 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1428 gtk_widget_show_all (priv->attachments_caption);
1429 } else if (image_file_id == -1) {
1430 close (image_file_id);
1439 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1442 ModestMsgEditWindowPrivate *priv;
1443 GtkWidget *dialog = NULL;
1445 gchar *uri = NULL, *filename = NULL;
1447 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1449 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1451 response = gtk_dialog_run (GTK_DIALOG (dialog));
1453 case GTK_RESPONSE_OK:
1454 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
1455 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1460 gtk_widget_destroy (dialog);
1464 GnomeVFSHandle *handle = NULL;
1465 GnomeVFSResult result;
1467 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1468 if (result == GNOME_VFS_OK) {
1469 TnyMimePart *mime_part;
1471 const gchar *mime_type = NULL;
1474 GnomeVFSFileInfo info;
1476 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1477 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1478 mime_part = tny_platform_factory_new_mime_part
1479 (modest_runtime_get_platform_factory ());
1480 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1482 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1484 content_id = g_strdup_printf ("%d", priv->last_cid);
1485 tny_mime_part_set_content_id (mime_part, content_id);
1486 g_free (content_id);
1489 basename = g_path_get_basename (filename);
1490 tny_mime_part_set_filename (mime_part, basename);
1493 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1494 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1496 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1497 gtk_widget_show_all (priv->attachments_caption);
1498 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1505 modest_msg_edit_window_attach_file_noninteractive (
1506 ModestMsgEditWindow *window,
1510 ModestMsgEditWindowPrivate *priv;
1512 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1517 file_id = g_open (filename, O_RDONLY, 0);
1518 if (file_id != -1) {
1519 TnyMimePart *mime_part;
1521 const gchar *mime_type;
1525 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1526 mime_part = tny_platform_factory_new_mime_part
1527 (modest_runtime_get_platform_factory ());
1528 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1530 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1532 content_id = g_strdup_printf ("%d", priv->last_cid);
1533 tny_mime_part_set_content_id (mime_part, content_id);
1534 g_free (content_id);
1537 basename = g_path_get_basename (filename);
1538 tny_mime_part_set_filename (mime_part, basename);
1541 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1542 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1544 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1545 gtk_widget_show_all (priv->attachments_caption);
1546 } else if (file_id == -1) {
1553 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1556 ModestMsgEditWindowPrivate *priv;
1557 gboolean clean_list = FALSE;
1559 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1560 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1562 if (att_list == NULL) {
1563 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1567 if (att_list == NULL) {
1568 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1570 GtkWidget *confirmation_dialog = NULL;
1571 gboolean dialog_response;
1573 if (att_list->next == NULL) {
1574 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1575 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1576 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1579 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1581 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1582 gtk_widget_destroy (confirmation_dialog);
1583 if (!dialog_response) {
1585 g_list_free (att_list);
1588 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1590 for (node = att_list; node != NULL; node = g_list_next (node)) {
1591 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1592 const gchar *att_id;
1593 priv->attachments = g_list_remove (priv->attachments, mime_part);
1595 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1597 att_id = tny_mime_part_get_content_id (mime_part);
1599 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1601 g_object_unref (mime_part);
1602 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1607 g_list_free (att_list);
1611 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1614 ModestMsgEditWindowPrivate *priv;
1615 GdkColor *new_color;
1616 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1618 #ifdef MODEST_HILDON_VERSION_0
1619 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1622 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1624 #endif /*MODEST_HILDON_VERSION_0*/
1626 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1628 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1633 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1636 ModestMsgEditWindowPrivate *priv;
1637 gint new_size_index;
1638 ModestMsgEditWindow *window;
1641 window = MODEST_MSG_EDIT_WINDOW (userdata);
1642 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1643 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1645 if (gtk_check_menu_item_get_active (menu_item)) {
1647 WPTextBufferFormat format;
1649 memset (&format, 0, sizeof (format));
1650 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1652 label = gtk_bin_get_child (GTK_BIN (menu_item));
1654 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1655 format.cs.font_size = TRUE;
1656 format.cs.text_position = TRUE;
1657 format.cs.font = TRUE;
1658 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1659 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1661 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1662 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1663 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1665 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1666 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1667 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1673 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1676 ModestMsgEditWindowPrivate *priv;
1677 gint new_font_index;
1678 ModestMsgEditWindow *window;
1681 window = MODEST_MSG_EDIT_WINDOW (userdata);
1682 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1683 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1685 if (gtk_check_menu_item_get_active (menu_item)) {
1688 label = gtk_bin_get_child (GTK_BIN (menu_item));
1690 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1692 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1693 (gpointer) new_font_index))
1694 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1696 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1697 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1698 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1704 modest_msg_edit_window_set_zoom (ModestWindow *window,
1707 ModestMsgEditWindowPrivate *priv;
1709 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1711 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1712 priv->zoom_level = zoom;
1713 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1717 modest_msg_edit_window_get_zoom (ModestWindow *window)
1719 ModestMsgEditWindowPrivate *priv;
1721 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1723 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1724 return priv->zoom_level;
1728 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1730 ModestWindowPrivate *parent_priv;
1731 GtkRadioAction *zoom_radio_action;
1732 GSList *group, *node;
1734 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1735 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1736 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1738 group = gtk_radio_action_get_group (zoom_radio_action);
1740 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1741 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1745 for (node = group; node != NULL; node = g_slist_next (node)) {
1746 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1747 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1755 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1757 ModestWindowPrivate *parent_priv;
1758 GtkRadioAction *zoom_radio_action;
1759 GSList *group, *node;
1761 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1762 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1763 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1765 group = gtk_radio_action_get_group (zoom_radio_action);
1767 for (node = group; node != NULL; node = g_slist_next (node)) {
1768 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1769 if (node->next != NULL) {
1770 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1773 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1781 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1783 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1784 ModestWindowPrivate *parent_priv;
1785 ModestWindowMgr *mgr;
1786 gboolean is_fullscreen;
1787 GtkAction *fs_toggle_action;
1790 mgr = modest_runtime_get_window_mgr ();
1791 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1793 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1795 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1796 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1797 if (is_fullscreen != active)
1798 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1806 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1808 ModestWindowPrivate *parent_priv;
1809 GtkAction *fs_toggle_action;
1812 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1814 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1815 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1816 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1820 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1823 ModestMsgEditWindowPrivate *priv = NULL;
1824 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1826 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1827 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1829 gtk_widget_show (priv->cc_caption);
1831 gtk_widget_hide (priv->cc_caption);
1832 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1836 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1839 ModestMsgEditWindowPrivate *priv = NULL;
1840 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1842 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1843 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1845 gtk_widget_show (priv->bcc_caption);
1847 gtk_widget_hide (priv->bcc_caption);
1848 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
1852 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1853 ModestRecptEditor *editor)
1855 ModestMsgEditWindowPrivate *priv;
1857 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1858 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1859 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1861 if (editor == NULL) {
1862 GtkWidget *view_focus;
1863 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1865 /* This code should be kept in sync with ModestRecptEditor. The
1866 textview inside the recpt editor is the one that really gets the
1867 focus. As it's inside a scrolled window, and this one inside the
1868 hbox recpt editor inherits from, we'll need to go up in the
1869 hierarchy to know if the text view is part of the recpt editor
1870 or if it's a different text entry */
1872 if (gtk_widget_get_parent (view_focus)) {
1873 GtkWidget *first_parent;
1875 first_parent = gtk_widget_get_parent (view_focus);
1876 if (gtk_widget_get_parent (first_parent) &&
1877 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1878 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1883 editor = MODEST_RECPT_EDITOR (priv->to_field);
1887 modest_address_book_select_addresses (editor);
1892 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1894 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1896 modest_msg_edit_window_open_addressbook (window, NULL);
1900 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1901 gboolean show_toolbar)
1903 ModestWindowPrivate *parent_priv;
1905 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1906 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1908 /* FIXME: we can not just use the code of
1909 modest_msg_edit_window_setup_toolbar because it has a
1910 mixture of both initialization and creation code. */
1913 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1915 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1919 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1920 TnyHeaderFlags priority_flags)
1922 ModestMsgEditWindowPrivate *priv;
1924 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1926 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1927 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1929 if (priv->priority_flags != priority_flags) {
1931 priv->priority_flags = priority_flags;
1933 switch (priority_flags) {
1934 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1935 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1936 gtk_widget_show (priv->priority_icon);
1938 case TNY_HEADER_FLAG_LOW_PRIORITY:
1939 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1940 gtk_widget_show (priv->priority_icon);
1943 gtk_widget_hide (priv->priority_icon);
1950 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1953 ModestMsgEditWindowPrivate *priv;
1954 gint current_format;
1956 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1958 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1960 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1961 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1963 if (current_format != file_format) {
1964 switch (file_format) {
1965 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1966 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1968 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1972 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1973 response = gtk_dialog_run (GTK_DIALOG (dialog));
1974 gtk_widget_destroy (dialog);
1975 if (response == GTK_RESPONSE_OK)
1976 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1980 update_dimmed (window);
1985 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1988 ModestMsgEditWindowPrivate *priv;
1989 WPTextBufferFormat oldfmt, fmt;
1990 gint old_position = 0;
1994 GdkColor *color = NULL;
1995 gboolean bold, bold_set, italic, italic_set;
1996 gboolean underline, underline_set;
1997 gboolean strikethrough, strikethrough_set;
1998 gboolean position_set;
1999 gboolean font_size_set, font_set, color_set;
2002 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2003 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2005 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
2007 /* First we get the currently selected font information */
2008 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2009 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2011 switch (oldfmt.text_position) {
2012 case TEXT_POSITION_NORMAL:
2015 case TEXT_POSITION_SUPERSCRIPT:
2023 g_object_set (G_OBJECT (dialog),
2024 "bold", oldfmt.bold != FALSE,
2025 "bold-set", !oldfmt.cs.bold,
2026 "underline", oldfmt.underline != FALSE,
2027 "underline-set", !oldfmt.cs.underline,
2028 "italic", oldfmt.italic != FALSE,
2029 "italic-set", !oldfmt.cs.italic,
2030 "strikethrough", oldfmt.strikethrough != FALSE,
2031 "strikethrough-set", !oldfmt.cs.strikethrough,
2032 "color", &oldfmt.color,
2033 "color-set", !oldfmt.cs.color,
2034 "size", wp_font_size[oldfmt.font_size],
2035 "size-set", !oldfmt.cs.font_size,
2036 "position", old_position,
2037 "position-set", !oldfmt.cs.text_position,
2038 "family", wp_get_font_name (oldfmt.font),
2039 "family-set", !oldfmt.cs.font,
2042 gtk_widget_show_all (dialog);
2043 response = gtk_dialog_run (GTK_DIALOG (dialog));
2044 if (response == GTK_RESPONSE_OK) {
2046 g_object_get( dialog,
2048 "bold-set", &bold_set,
2049 "underline", &underline,
2050 "underline-set", &underline_set,
2052 "italic-set", &italic_set,
2053 "strikethrough", &strikethrough,
2054 "strikethrough-set", &strikethrough_set,
2056 "color-set", &color_set,
2058 "size-set", &font_size_set,
2059 "family", &font_name,
2060 "family-set", &font_set,
2061 "position", &position,
2062 "position-set", &position_set,
2067 if (response == GTK_RESPONSE_OK) {
2068 memset(&fmt, 0, sizeof(fmt));
2074 fmt.italic = italic;
2075 fmt.cs.italic = TRUE;
2077 if (underline_set) {
2078 fmt.underline = underline;
2079 fmt.cs.underline = TRUE;
2081 if (strikethrough_set) {
2082 fmt.strikethrough = strikethrough;
2083 fmt.cs.strikethrough = TRUE;
2088 ? TEXT_POSITION_NORMAL
2089 : ( ( position == 1 )
2090 ? TEXT_POSITION_SUPERSCRIPT
2091 : TEXT_POSITION_SUBSCRIPT );
2092 fmt.cs.text_position = TRUE;
2096 fmt.cs.color = TRUE;
2099 fmt.font = wp_get_font_index(font_name,
2104 if (font_size_set) {
2105 fmt.font_size = wp_get_font_size_index(
2106 font_size, DEFAULT_FONT_SIZE);
2107 fmt.cs.font_size = TRUE;
2109 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2111 gtk_widget_destroy (dialog);
2113 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2117 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2119 ModestMsgEditWindowPrivate *priv;
2121 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2122 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2124 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2126 update_dimmed (window);
2131 update_dimmed (ModestMsgEditWindow *window)
2133 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2134 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2138 gboolean editor_focused;
2140 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2141 editor_focused = gtk_widget_is_focus (priv->msg_body);
2143 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2144 gtk_action_set_sensitive (action, rich_text && editor_focused);
2145 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2146 gtk_action_set_sensitive (action, rich_text && editor_focused);
2147 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2148 gtk_action_set_sensitive (action, rich_text && editor_focused);
2149 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2150 gtk_action_set_sensitive (action, rich_text && editor_focused);
2151 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2152 gtk_action_set_sensitive (action, rich_text && editor_focused);
2153 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2154 gtk_action_set_sensitive (action, rich_text && editor_focused);
2155 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2156 gtk_action_set_sensitive (action, rich_text && editor_focused);
2157 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2158 gtk_action_set_sensitive (action, rich_text && editor_focused);
2159 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2160 gtk_action_set_sensitive (action, rich_text && editor_focused);
2161 widget = priv->font_color_button;
2162 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2163 widget = priv->font_size_toolitem;
2164 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2165 widget = priv->font_face_toolitem;
2166 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2170 setup_insensitive_handlers (ModestMsgEditWindow *window)
2172 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2173 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2176 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2177 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2178 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2179 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2181 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2182 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2183 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2184 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2185 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2186 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2187 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2188 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2189 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2190 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2191 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2192 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2193 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2194 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2195 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2196 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2197 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2198 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2199 widget = priv->font_color_button;
2200 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2201 widget = priv->font_size_toolitem;
2202 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2203 widget = priv->font_face_toolitem;
2204 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2209 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2211 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2214 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2215 gtk_action_set_sensitive (action, can_undo);
2219 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2222 GtkTextIter match_start, match_end;
2224 if (image_id == NULL)
2227 gtk_text_buffer_get_start_iter (buffer, &iter);
2229 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2230 GSList *tags = gtk_text_iter_get_tags (&match_start);
2232 for (node = tags; node != NULL; node = g_slist_next (node)) {
2233 GtkTextTag *tag = (GtkTextTag *) node->data;
2234 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2235 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2236 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2238 offset = gtk_text_iter_get_offset (&match_start);
2239 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2240 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2244 gtk_text_iter_forward_char (&iter);
2249 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2251 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2252 GtkTextIter real_start, real_end;
2253 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2255 if (gtk_text_iter_compare (start, end) > 0) {
2259 real_start = *start;
2263 GSList *tags = gtk_text_iter_get_tags (&real_start);
2265 for (node = tags; node != NULL; node = g_slist_next (node)) {
2266 GtkTextTag *tag = (GtkTextTag *) node->data;
2267 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2268 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2270 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2272 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2275 } while (gtk_text_iter_forward_char (&real_start)&&
2276 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2280 msg_body_focus (GtkWidget *focus,
2281 GdkEventFocus *event,
2285 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2290 recpt_field_changed (GtkTextBuffer *buffer,
2291 ModestMsgEditWindow *editor)
2293 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2294 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2295 GtkTextBuffer *to_buffer, *cc_buffer, *bcc_buffer;
2296 gboolean dim = FALSE;
2299 to_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field));
2300 cc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field));
2301 bcc_buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field));
2303 dim = ((gtk_text_buffer_get_char_count (to_buffer) +
2304 gtk_text_buffer_get_char_count (cc_buffer) +
2305 gtk_text_buffer_get_char_count (bcc_buffer)) == 0);
2307 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2308 gtk_action_set_sensitive (action, !dim);
2309 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2310 gtk_action_set_sensitive (action, !dim);
2314 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2316 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2320 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2322 gboolean rich_text, editor_focused;
2324 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2325 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2326 editor_focused = gtk_widget_is_focus (priv->msg_body);
2329 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2330 else if (!editor_focused)
2331 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2335 reset_modified (ModestMsgEditWindow *editor)
2337 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2338 GtkTextBuffer *buffer;
2340 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2341 gtk_text_buffer_set_modified (buffer, FALSE);
2342 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2343 gtk_text_buffer_set_modified (buffer, FALSE);
2344 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2345 gtk_text_buffer_set_modified (buffer, FALSE);
2346 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2350 is_modified (ModestMsgEditWindow *editor)
2352 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2353 GtkTextBuffer *buffer;
2355 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2356 if (gtk_text_buffer_get_modified (buffer))
2358 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2359 if (gtk_text_buffer_get_modified (buffer))
2361 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2362 if (gtk_text_buffer_get_modified (buffer))
2364 if (gtk_text_buffer_get_modified (priv->text_buffer))
2371 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2373 ModestMsgEditWindowPrivate *priv = NULL;
2375 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2376 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2378 /* check if there's no recipient added */
2379 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2380 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2381 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2382 /* no recipient contents, then select contacts */
2383 modest_msg_edit_window_open_addressbook (window, NULL);
2387 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2389 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2391 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2394 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2401 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2402 ModestMsgEditWindow *window)
2404 modest_msg_edit_window_attach_file (window);
2408 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2410 ModestMsgEditWindow *window)
2412 ModestWindowPrivate *parent_priv;
2417 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2418 selection = gtk_clipboard_wait_for_text (clipboard);
2419 focused = gtk_window_get_focus (GTK_WINDOW (window));
2421 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2422 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2423 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2424 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2428 update_window_title (ModestMsgEditWindow *window)
2430 ModestMsgEditWindowPrivate *priv = NULL;
2431 const gchar *subject;
2433 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2434 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2435 if (subject == NULL || subject[0] == '\0')
2436 subject = _("mail_va_new_email");
2438 gtk_window_set_title (GTK_WINDOW (window), subject);
2443 subject_field_changed (GtkEditable *editable,
2444 ModestMsgEditWindow *window)
2446 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2447 update_window_title (window);
2448 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);