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 to_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 (to_field_changed), obj);
413 to_field_changed (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field)), MODEST_MSG_EDIT_WINDOW (obj));
414 g_signal_connect (G_OBJECT (priv->subject_field), "changed", G_CALLBACK (subject_field_changed), obj);
416 priv->scroll = gtk_scrolled_window_new (NULL, NULL);
417 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
418 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (priv->scroll), GTK_SHADOW_NONE);
420 main_vbox = gtk_vbox_new (FALSE, DEFAULT_MAIN_VBOX_SPACING);
422 gtk_box_pack_start (GTK_BOX(main_vbox), priv->header_box, FALSE, FALSE, 0);
423 frame = gtk_frame_new (NULL);
424 gtk_box_pack_start (GTK_BOX(main_vbox), frame, TRUE, TRUE, 0);
426 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->scroll), main_vbox);
427 gtk_container_set_focus_vadjustment (GTK_CONTAINER (main_vbox), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
428 gtk_widget_show_all (GTK_WIDGET(priv->scroll));
430 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL)) {
431 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
432 gtk_widget_hide (priv->cc_caption);
434 if (!modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL)) {
435 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
436 gtk_widget_hide (priv->bcc_caption);
439 gtk_container_add (GTK_CONTAINER(obj), priv->scroll);
440 scroll_area = modest_scroll_area_new (priv->scroll, priv->msg_body);
441 gtk_container_add (GTK_CONTAINER (frame), scroll_area);
442 gtk_container_set_focus_vadjustment (GTK_CONTAINER (scroll_area),
443 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (priv->scroll)));
445 priv->clipboard_change_handler_id = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change",
446 G_CALLBACK (modest_msg_edit_window_clipboard_owner_change), obj);
452 modest_msg_edit_window_finalize (GObject *obj)
454 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
457 if (priv->clipboard_change_handler_id > 0) {
458 g_signal_handler_disconnect (gtk_clipboard_get (GDK_SELECTION_PRIMARY), priv->clipboard_change_handler_id);
459 priv->clipboard_change_handler_id = 0;
462 /* This had to stay alive for as long as the combobox that used it: */
463 modest_pair_list_free (priv->from_field_protos);
465 G_OBJECT_CLASS(parent_class)->finalize (obj);
469 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMsgEditWindow *self)
471 GtkWidget *close_dialog;
472 ModestMsgEditWindowPrivate *priv;
475 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
476 modest_window_save_state (MODEST_WINDOW (self));
477 if (is_modified (self)) {
478 close_dialog = hildon_note_new_confirmation (GTK_WINDOW (self), _("mcen_nc_no_email_message_modified_save_changes"));
479 response = gtk_dialog_run (GTK_DIALOG (close_dialog));
480 gtk_widget_destroy (close_dialog);
482 if (response != GTK_RESPONSE_CANCEL) {
483 modest_ui_actions_on_save_to_drafts (NULL, self);
486 /* /\* remove old message from drafts *\/ */
487 /* if (priv->draft_msg) { */
488 /* TnyHeader *header = tny_msg_get_header (priv->draft_msg); */
489 /* TnyAccount *account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(), */
491 /* TNY_ACCOUNT_TYPE_STORE); */
492 /* TnyFolder *folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS); */
493 /* g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); */
494 /* g_return_val_if_fail (TNY_IS_FOLDER (folder), FALSE); */
495 /* tny_folder_remove_msg (folder, header, NULL); */
496 /* g_object_unref (folder); */
497 /* g_object_unref (header); */
498 /* g_object_unref (priv->draft_msg); */
499 /* priv->draft_msg = NULL; */
501 gtk_widget_destroy (GTK_WIDGET (self));
507 menubar_to_menu (GtkUIManager *ui_manager)
509 GtkWidget *main_menu;
513 /* Create new main menu */
514 main_menu = gtk_menu_new();
516 /* Get the menubar from the UI manager */
517 menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar");
519 iter = gtk_container_get_children (GTK_CONTAINER (menubar));
523 menu = GTK_WIDGET (iter->data);
524 gtk_widget_reparent(menu, main_menu);
526 iter = g_list_next (iter);
533 set_msg (ModestMsgEditWindow *self, TnyMsg *msg)
536 const gchar *to, *cc, *bcc, *subject;
538 ModestMsgEditWindowPrivate *priv;
541 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
542 g_return_if_fail (TNY_IS_MSG (msg));
544 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
546 header = tny_msg_get_header (msg);
547 to = tny_header_get_to (header);
548 cc = tny_header_get_cc (header);
549 bcc = tny_header_get_bcc (header);
550 subject = tny_header_get_subject (header);
553 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->to_field), to);
555 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->cc_field), cc);
557 modest_recpt_editor_set_recipients (MODEST_RECPT_EDITOR (priv->bcc_field), bcc);
559 gtk_entry_set_text (GTK_ENTRY(priv->subject_field), subject);
561 update_window_title (self);
563 /* gtk_text_buffer_set_can_paste_rich_text (priv->text_buffer, TRUE); */
564 wp_text_buffer_reset_buffer (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
565 body = modest_tny_msg_get_body (msg, TRUE);
567 if ((body == NULL)||(body[0] == '\0')) {
569 body = modest_text_utils_convert_to_html ("");
571 wp_text_buffer_load_document_begin (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
572 wp_text_buffer_load_document_write (WP_TEXT_BUFFER (priv->text_buffer),
575 wp_text_buffer_load_document_end (WP_TEXT_BUFFER (priv->text_buffer));
578 /* Get the default format required from configuration */
579 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) {
580 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
583 /* Set the default focus depending on having already a To: field or not */
584 if ((!to)||(*to == '\0')) {
585 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
587 gtk_widget_grab_focus (priv->msg_body);
590 /* TODO: lower priority, select in the From: combo to the
591 value that comes from msg <- not sure, should it be
594 /* Add attachments to the view */
595 modest_attachments_view_set_message (MODEST_ATTACHMENTS_VIEW (priv->attachments_view), msg);
596 if (priv->attachments == NULL)
597 gtk_widget_hide_all (priv->attachments_caption);
599 gtk_text_buffer_get_start_iter (priv->text_buffer, &iter);
600 gtk_text_buffer_place_cursor (priv->text_buffer, &iter);
602 reset_modified (self);
604 update_dimmed (self);
605 text_buffer_can_undo (priv->text_buffer, FALSE, self);
607 priv->draft_msg = msg;
611 menu_tool_button_clicked_popup (GtkMenuToolButton *item,
614 GList *item_children, *node;
615 GtkWidget *bin_child;
617 bin_child = gtk_bin_get_child (GTK_BIN(item));
619 item_children = gtk_container_get_children (GTK_CONTAINER (bin_child));
621 for (node = item_children; node != NULL; node = g_list_next (node)) {
622 if (GTK_IS_TOGGLE_BUTTON (node->data)) {
623 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (node->data), TRUE);
626 g_list_free (item_children);
630 menu_tool_button_dont_expand (GtkMenuToolButton *item)
633 GList *item_children, *node;
635 box = gtk_bin_get_child (GTK_BIN (item));
636 gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
637 item_children = gtk_container_get_children (GTK_CONTAINER (box));
639 for (node = item_children; node != NULL; node = g_list_next (node)) {
640 gtk_box_set_child_packing (GTK_BOX (box), GTK_WIDGET (node->data), TRUE, TRUE, 0, GTK_PACK_START);
641 if (GTK_IS_TOGGLE_BUTTON (node->data))
642 gtk_button_set_alignment (GTK_BUTTON (node->data), 0.0, 0.5);
643 else if (GTK_IS_BUTTON (node->data))
644 gtk_button_set_alignment (GTK_BUTTON (node->data), 1.0, 0.5);
646 g_list_free (item_children);
651 modest_msg_edit_window_setup_toolbar (ModestMsgEditWindow *window)
653 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
654 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
655 GtkWidget *placeholder;
656 GtkWidget *tool_item;
661 GtkWidget *sizes_menu;
662 GtkWidget *fonts_menu;
663 GSList *radio_group = NULL;
668 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar");
669 hildon_window_add_toolbar (HILDON_WINDOW (window), GTK_TOOLBAR (parent_priv->toolbar));
671 /* should we hide the toolbar? */
672 if (!modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_SHOW_TOOLBAR, NULL))
673 gtk_widget_hide (parent_priv->toolbar);
675 /* Font color placeholder */
676 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontColor");
677 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
680 tool_item = GTK_WIDGET (gtk_tool_item_new ());
681 priv->font_color_button = hildon_color_button_new ();
682 GTK_WIDGET_UNSET_FLAGS (tool_item, GTK_CAN_FOCUS);
683 GTK_WIDGET_UNSET_FLAGS (priv->font_color_button, GTK_CAN_FOCUS);
684 gtk_container_add (GTK_CONTAINER (tool_item), priv->font_color_button);
685 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
686 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
687 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
688 g_signal_connect_swapped (G_OBJECT (priv->font_color_button), "notify::color", G_CALLBACK (modest_msg_edit_window_color_button_change), window);
690 /* Font size and face placeholder */
691 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/FontAttributes");
692 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
694 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
695 priv->size_tool_button_label = gtk_label_new (NULL);
696 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[DEFAULT_FONT_SIZE]);
697 markup = g_strconcat ("<span font_family='", DEFAULT_SIZE_BUTTON_FONT_FAMILY, "'>",
698 size_text,"</span>", NULL);
699 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
701 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->size_tool_button_label);
702 sizes_menu = gtk_menu_new ();
703 priv->size_items_group = NULL;
705 for (size_index = 0; size_index < WP_FONT_SIZE_COUNT; size_index++) {
706 GtkWidget *size_menu_item;
708 snprintf(size_text, sizeof(size_text), "%d", wp_font_size[size_index]);
709 size_menu_item = gtk_radio_menu_item_new_with_label (radio_group, size_text);
710 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (size_menu_item));
711 gtk_menu_shell_append (GTK_MENU_SHELL (sizes_menu), size_menu_item);
712 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (size_menu_item), (wp_font_size[size_index] == 12));
713 gtk_widget_show (size_menu_item);
715 priv->size_items_group = g_slist_prepend (priv->size_items_group, size_menu_item);
719 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
720 GtkWidget *item = (GtkWidget *) node->data;
721 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_size_change),
725 priv->size_items_group = g_slist_reverse (priv->size_items_group);
726 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), sizes_menu);
727 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
728 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
729 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
730 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
731 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
732 priv->font_size_toolitem = tool_item;
735 tool_item = GTK_WIDGET (gtk_menu_tool_button_new (NULL, NULL));
736 priv->font_tool_button_label = gtk_label_new (NULL);
737 markup = g_strconcat ("<span font_family='", wp_get_font_name(DEFAULT_FONT), "'>Tt</span>", NULL);
738 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
740 gtk_tool_button_set_label_widget (GTK_TOOL_BUTTON (tool_item), priv->font_tool_button_label);
741 fonts_menu = gtk_menu_new ();
742 priv->font_items_group = NULL;
744 for (font_index = 0; font_index < wp_get_font_count (); font_index++) {
745 GtkWidget *font_menu_item;
746 GtkWidget *child_label;
748 font_menu_item = gtk_radio_menu_item_new_with_label (radio_group, "");
749 child_label = gtk_bin_get_child (GTK_BIN (font_menu_item));
750 markup = g_strconcat ("<span font_family='", wp_get_font_name (font_index),"'>",
751 wp_get_font_name (font_index), "</span>", NULL);
752 gtk_label_set_markup (GTK_LABEL (child_label), markup);
755 radio_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (font_menu_item));
756 gtk_menu_shell_append (GTK_MENU_SHELL (fonts_menu), font_menu_item);
757 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (font_menu_item), (font_index == DEFAULT_FONT));
758 gtk_widget_show (font_menu_item);
760 priv->font_items_group = g_slist_prepend (priv->font_items_group, font_menu_item);
763 for (node = radio_group; node != NULL; node = g_slist_next (node)) {
764 GtkWidget *item = (GtkWidget *) node->data;
765 g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (modest_msg_edit_window_font_change),
768 priv->font_items_group = g_slist_reverse (priv->font_items_group);
769 gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), fonts_menu);
770 g_signal_connect (G_OBJECT (tool_item), "clicked", G_CALLBACK (menu_tool_button_clicked_popup), NULL);
771 gtk_toolbar_insert (GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM (tool_item), insert_index);
772 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
773 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
774 menu_tool_button_dont_expand (GTK_MENU_TOOL_BUTTON (tool_item));
775 priv->font_face_toolitem = tool_item;
777 /* Set expand and homogeneous for remaining items */
778 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
779 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
780 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
781 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
782 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
783 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
784 tool_item = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
785 gtk_tool_item_set_expand (GTK_TOOL_ITEM (tool_item), TRUE);
786 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (tool_item), TRUE);
794 modest_msg_edit_window_new (TnyMsg *msg, const gchar *account_name)
797 ModestWindowPrivate *parent_priv;
798 ModestMsgEditWindowPrivate *priv;
799 GtkActionGroup *action_group;
800 GError *error = NULL;
801 GdkPixbuf *window_icon = NULL;
804 gboolean prefer_formatted;
807 g_return_val_if_fail (msg, NULL);
809 obj = g_object_new(MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
811 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (obj);
812 parent_priv = MODEST_WINDOW_GET_PRIVATE (obj);
814 parent_priv->ui_manager = gtk_ui_manager_new();
815 action_group = gtk_action_group_new ("ModestMsgEditWindowActions");
816 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
818 /* Add common actions */
819 gtk_action_group_add_actions (action_group,
820 modest_msg_edit_action_entries,
821 G_N_ELEMENTS (modest_msg_edit_action_entries),
823 gtk_action_group_add_toggle_actions (action_group,
824 modest_msg_edit_toggle_action_entries,
825 G_N_ELEMENTS (modest_msg_edit_toggle_action_entries),
827 gtk_action_group_add_radio_actions (action_group,
828 modest_msg_edit_alignment_radio_action_entries,
829 G_N_ELEMENTS (modest_msg_edit_alignment_radio_action_entries),
831 G_CALLBACK (modest_ui_actions_on_change_justify),
833 gtk_action_group_add_radio_actions (action_group,
834 modest_msg_edit_zoom_action_entries,
835 G_N_ELEMENTS (modest_msg_edit_zoom_action_entries),
837 G_CALLBACK (modest_ui_actions_on_change_zoom),
839 gtk_action_group_add_radio_actions (action_group,
840 modest_msg_edit_priority_action_entries,
841 G_N_ELEMENTS (modest_msg_edit_priority_action_entries),
843 G_CALLBACK (modest_ui_actions_msg_edit_on_change_priority),
845 gtk_action_group_add_radio_actions (action_group,
846 modest_msg_edit_file_format_action_entries,
847 G_N_ELEMENTS (modest_msg_edit_file_format_action_entries),
848 modest_conf_get_bool (modest_runtime_get_conf (), MODEST_CONF_PREFER_FORMATTED_TEXT, NULL),
849 G_CALLBACK (modest_ui_actions_msg_edit_on_change_file_format),
851 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
852 g_object_unref (action_group);
854 /* Load the UI definition */
855 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-edit-window-ui.xml", &error);
857 g_warning ("Could not merge modest-msg-edit-window-ui.xml: %s", error->message);
858 g_clear_error (&error);
861 /* Add accelerators */
862 gtk_window_add_accel_group (GTK_WINDOW (obj),
863 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
866 parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager);
867 hildon_window_set_menu (HILDON_WINDOW (obj), GTK_MENU (parent_priv->menubar));
870 init_window (MODEST_MSG_EDIT_WINDOW(obj));
872 restore_settings (MODEST_MSG_EDIT_WINDOW(obj));
874 gtk_window_set_icon_from_file (GTK_WINDOW(obj), MODEST_APP_ICON, NULL);
876 g_signal_connect (G_OBJECT(obj), "delete-event",
877 G_CALLBACK(on_delete_event), obj);
879 modest_window_set_active_account (MODEST_WINDOW(obj), account_name);
881 modest_msg_edit_window_setup_toolbar (MODEST_MSG_EDIT_WINDOW (obj));
883 setup_insensitive_handlers (MODEST_MSG_EDIT_WINDOW (obj));
885 set_msg (MODEST_MSG_EDIT_WINDOW (obj), msg);
887 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (obj));
889 /* Set window icon */
890 window_icon = modest_platform_get_icon (MODEST_APP_MSG_EDIT_ICON);
891 gtk_window_set_icon (GTK_WINDOW (obj), window_icon);
893 /* Dim at start clipboard actions */
894 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
895 gtk_action_set_sensitive (action, FALSE);
896 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
897 gtk_action_set_sensitive (action, FALSE);
899 /* set initial state of cc and bcc */
900 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewCcFieldMenu");
901 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
902 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, NULL));
903 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewBccFieldMenu");
904 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
905 modest_conf_get_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, NULL));
907 /* Setup the file format */
908 conf = modest_runtime_get_conf ();
909 prefer_formatted = modest_conf_get_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, &error);
911 g_clear_error (&error);
912 file_format = MODEST_FILE_FORMAT_FORMATTED_TEXT;
914 file_format = (prefer_formatted) ?
915 MODEST_FILE_FORMAT_FORMATTED_TEXT :
916 MODEST_FILE_FORMAT_PLAIN_TEXT;
917 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (obj), file_format);
919 return (ModestWindow*) obj;
923 get_formatted_data_cb (const gchar *buffer, gpointer user_data)
925 GString **string_buffer = (GString **) user_data;
927 *string_buffer = g_string_append (*string_buffer, buffer);
933 * @result: A new string which should be freed with g_free().
936 get_formatted_data (ModestMsgEditWindow *edit_window)
938 ModestMsgEditWindowPrivate *priv;
939 GString *string_buffer = g_string_new ("");
941 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
943 wp_text_buffer_save_document (WP_TEXT_BUFFER(priv->text_buffer), get_formatted_data_cb, &string_buffer);
945 return g_string_free (string_buffer, FALSE);
950 modest_msg_edit_window_get_msg_data (ModestMsgEditWindow *edit_window)
953 const gchar *account_name;
954 ModestMsgEditWindowPrivate *priv;
956 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window), NULL);
958 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (edit_window);
960 account_name = modest_combo_box_get_active_id (MODEST_COMBO_BOX (priv->from_field));
961 g_return_val_if_fail (account_name, NULL);
964 /* don't free these (except from) */
965 data = g_slice_new0 (MsgData);
966 data->from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
968 data->account_name = g_strdup (account_name);
969 data->to = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->to_field)));
970 data->cc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->cc_field)));
971 data->bcc = g_strdup (modest_recpt_editor_get_recipients (MODEST_RECPT_EDITOR (priv->bcc_field)));
972 data->subject = g_strdup (gtk_entry_get_text (GTK_ENTRY (priv->subject_field)));
973 if (priv->draft_msg) {
974 data->draft_msg = g_object_ref (priv->draft_msg);
976 data->draft_msg = NULL;
979 GtkTextBuffer *buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body));
981 gtk_text_buffer_get_bounds (buf, &b, &e);
982 data->plain_body = g_strdup (gtk_text_buffer_get_text (priv->text_buffer, &b, &e, FALSE)); /* returns a copy */
984 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer)))
985 data->html_body = get_formatted_data (edit_window); /* returns a copy. */
987 data->html_body = NULL;
989 data->attachments = priv->attachments; /* TODO: copy and free ? */
990 data->priority_flags = priv->priority_flags;
995 /* TODO: We must duplicate this implementation for GNOME and Maemo, but that is unwise. */
997 modest_msg_edit_window_free_msg_data (ModestMsgEditWindow *edit_window,
1000 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (edit_window));
1008 g_free (data->subject);
1009 g_free (data->plain_body);
1010 g_free (data->html_body);
1011 if (data->draft_msg != NULL) {
1012 g_object_unref (data->draft_msg);
1013 data->draft_msg = NULL;
1015 g_free (data->account_name);
1017 /* TODO: Free data->attachments? */
1019 g_slice_free (MsgData, data);
1023 modest_msg_edit_window_get_format (ModestMsgEditWindow *self)
1026 ModestMsgEditWindowPrivate *priv = NULL;
1027 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), MODEST_MSG_EDIT_FORMAT_HTML);
1029 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1031 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
1033 return MODEST_MSG_EDIT_FORMAT_HTML;
1035 return MODEST_MSG_EDIT_FORMAT_TEXT;
1039 modest_msg_edit_window_set_format (ModestMsgEditWindow *self,
1040 ModestMsgEditFormat format)
1042 ModestMsgEditWindowPrivate *priv;
1044 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1045 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1048 case MODEST_MSG_EDIT_FORMAT_HTML:
1049 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1051 case MODEST_MSG_EDIT_FORMAT_TEXT:
1052 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1055 g_return_if_reached ();
1059 ModestMsgEditFormatState *
1060 modest_msg_edit_window_get_format_state (ModestMsgEditWindow *self)
1062 ModestMsgEditFormatState *format_state = NULL;
1063 ModestMsgEditWindowPrivate *priv;
1064 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1066 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self), NULL);
1067 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1069 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, TRUE);
1071 format_state = g_new0 (ModestMsgEditFormatState, 1);
1072 format_state->bold = buffer_format->bold&0x1;
1073 format_state->italics = buffer_format->italic&0x1;
1074 format_state->bullet = buffer_format->bullet&0x1;
1075 format_state->color = buffer_format->color;
1076 format_state->font_size = buffer_format->font_size;
1077 format_state->font_family = wp_get_font_name (buffer_format->font);
1078 format_state->justification = buffer_format->justification;
1079 g_free (buffer_format);
1081 return format_state;
1086 modest_msg_edit_window_set_format_state (ModestMsgEditWindow *self,
1087 const ModestMsgEditFormatState *format_state)
1089 ModestMsgEditWindowPrivate *priv;
1090 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1091 WPTextBufferFormat *current_format = g_new0 (WPTextBufferFormat, 1);
1092 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1093 g_return_if_fail (format_state != NULL);
1095 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (self);
1096 gtk_widget_grab_focus (priv->msg_body);
1097 buffer_format->bold = (format_state->bold != FALSE);
1098 buffer_format->italic = (format_state->italics != FALSE);
1099 buffer_format->color = format_state->color;
1100 buffer_format->font_size = format_state->font_size;
1101 buffer_format->font = wp_get_font_index (format_state->font_family, 0);
1102 buffer_format->justification = format_state->justification;
1103 buffer_format->bullet = format_state->bullet;
1105 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), current_format, TRUE);
1107 buffer_format->cs.bold = ((buffer_format->bold&0x1) != (current_format->bold&0x1));
1108 buffer_format->cs.italic = ((buffer_format->italic&0x1) != (current_format->italic&0x1));
1109 buffer_format->cs.color = gdk_color_equal(&(buffer_format->color), &(current_format->color));
1110 buffer_format->cs.font_size = (buffer_format->font_size != current_format->font_size);
1111 buffer_format->cs.font = (buffer_format->font != current_format->font);
1112 buffer_format->cs.justification = (buffer_format->justification != current_format->justification);
1113 buffer_format->cs.bullet = (buffer_format->bullet != current_format->bullet);
1115 wp_text_buffer_freeze (WP_TEXT_BUFFER (priv->text_buffer));
1116 if (buffer_format->cs.bold) {
1117 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->bold&0x1));
1119 if (buffer_format->cs.italic) {
1120 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_ITALIC, (gpointer) (buffer_format->italic&0x1));
1122 if (buffer_format->cs.color) {
1123 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) (&(buffer_format->color)));
1125 if (buffer_format->cs.font_size) {
1126 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font_size));
1128 if (buffer_format->cs.justification) {
1129 switch (buffer_format->justification) {
1130 case GTK_JUSTIFY_LEFT:
1131 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_LEFT, (gpointer) TRUE);
1133 case GTK_JUSTIFY_CENTER:
1134 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_CENTER, (gpointer) TRUE);
1136 case GTK_JUSTIFY_RIGHT:
1137 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_RIGHT, (gpointer) TRUE);
1144 if (buffer_format->cs.font) {
1145 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BOLD, (gpointer) (buffer_format->font));
1147 if (buffer_format->cs.bullet) {
1148 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_BULLET, (gpointer) (buffer_format->bullet));
1150 /* wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), buffer_format); */
1151 wp_text_buffer_thaw (WP_TEXT_BUFFER (priv->text_buffer));
1153 g_free (current_format);
1158 toggle_action_set_active_block_notify (GtkToggleAction *action,
1161 GSList *proxies = NULL;
1163 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1164 proxies != NULL; proxies = g_slist_next (proxies)) {
1165 GtkWidget *widget = (GtkWidget *) proxies->data;
1166 gtk_action_block_activate_from (GTK_ACTION (action), widget);
1169 gtk_toggle_action_set_active (action, value);
1171 for (proxies = gtk_action_get_proxies (GTK_ACTION (action));
1172 proxies != NULL; proxies = g_slist_next (proxies)) {
1173 GtkWidget *widget = (GtkWidget *) proxies->data;
1174 gtk_action_unblock_activate_from (GTK_ACTION (action), widget);
1179 text_buffer_refresh_attributes (WPTextBuffer *buffer, ModestMsgEditWindow *window)
1181 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1183 ModestWindowPrivate *parent_priv;
1184 ModestMsgEditWindowPrivate *priv;
1185 GtkWidget *new_size_menuitem;
1186 GtkWidget *new_font_menuitem;
1188 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1189 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1191 if (wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))) {
1192 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatFormattedTextMenu");
1193 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1194 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1196 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/FileFormatMenu/FileFormatPlainTextMenu");
1197 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
1198 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), TRUE);
1201 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1203 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
1204 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bold);
1206 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
1207 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->italic);
1209 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
1210 toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), buffer_format->bullet);
1212 g_signal_handlers_block_by_func (G_OBJECT (priv->font_color_button),
1213 G_CALLBACK (modest_msg_edit_window_color_button_change),
1215 hildon_color_button_set_color (HILDON_COLOR_BUTTON (priv->font_color_button), & (buffer_format->color));
1216 g_signal_handlers_unblock_by_func (G_OBJECT (priv->font_color_button),
1217 G_CALLBACK (modest_msg_edit_window_color_button_change),
1220 new_size_menuitem = GTK_WIDGET ((g_slist_nth (priv->size_items_group,
1221 buffer_format->font_size))->data);
1222 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_size_menuitem))) {
1226 label = gtk_bin_get_child (GTK_BIN (new_size_menuitem));
1227 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1228 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1230 g_signal_handlers_block_by_func (G_OBJECT (new_size_menuitem),
1231 G_CALLBACK (modest_msg_edit_window_size_change),
1233 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_size_menuitem), TRUE);
1234 g_signal_handlers_unblock_by_func (G_OBJECT (new_size_menuitem),
1235 G_CALLBACK (modest_msg_edit_window_size_change),
1239 new_font_menuitem = GTK_WIDGET ((g_slist_nth (priv->font_items_group,
1240 buffer_format->font))->data);
1241 if (!gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (new_font_menuitem))) {
1245 label = gtk_bin_get_child (GTK_BIN (new_font_menuitem));
1246 markup = g_strconcat ("<span font_family='", gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1247 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1249 g_signal_handlers_block_by_func (G_OBJECT (new_font_menuitem),
1250 G_CALLBACK (modest_msg_edit_window_font_change),
1252 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (new_font_menuitem), TRUE);
1253 g_signal_handlers_unblock_by_func (G_OBJECT (new_font_menuitem),
1254 G_CALLBACK (modest_msg_edit_window_font_change),
1258 g_free (buffer_format);
1264 modest_msg_edit_window_select_color (ModestMsgEditWindow *window)
1267 WPTextBufferFormat *buffer_format = g_new0 (WPTextBufferFormat, 1);
1268 ModestMsgEditWindowPrivate *priv;
1269 GtkWidget *dialog = NULL;
1271 const GdkColor *new_color = NULL;
1273 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1274 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), buffer_format, FALSE);
1276 #ifdef MODEST_HILDON_VERSION_0
1277 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1278 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog), &(buffer_format->color));
1280 dialog = hildon_color_chooser_new ();
1281 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog), &(buffer_format->color));
1282 #endif /*MODEST_HILDON_VERSION_0*/
1283 g_free (buffer_format);
1285 response = gtk_dialog_run (GTK_DIALOG (dialog));
1287 case GTK_RESPONSE_OK: {
1288 #ifdef MODEST_HILDON_VERSION_0
1289 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1292 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1294 #endif /*MODEST_HILDON_VERSION_0*/
1301 gtk_widget_destroy (dialog);
1303 if (new_color != NULL)
1304 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1309 modest_msg_edit_window_select_background_color (ModestMsgEditWindow *window)
1312 ModestMsgEditWindowPrivate *priv;
1313 GtkWidget *dialog = NULL;
1315 GdkColor *old_color = NULL;
1316 const GdkColor *new_color = NULL;
1318 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1319 old_color = (GdkColor*)wp_text_buffer_get_background_color (WP_TEXT_BUFFER (priv->text_buffer));
1321 #ifdef MODEST_HILDON_VERSION_0
1322 dialog = hildon_color_selector_new (GTK_WINDOW (window));
1323 hildon_color_selector_set_color (HILDON_COLOR_SELECTOR (dialog),(GdkColor*)old_color);
1325 dialog = hildon_color_chooser_new ();
1326 hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (dialog),(GdkColor*)old_color);
1327 #endif /*MODEST_HILDON_VERSION_9*/
1329 response = gtk_dialog_run (GTK_DIALOG (dialog));
1331 case GTK_RESPONSE_OK: {
1332 #ifdef MODEST_HILDON_VERSION_0
1333 new_color = hildon_color_selector_get_color (HILDON_COLOR_SELECTOR (dialog));
1336 hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER(dialog), &col);
1338 #endif /*MODEST_HILDON_VERSION_0*/
1344 gtk_widget_destroy (dialog);
1346 if (new_color != NULL)
1347 wp_text_buffer_set_background_color (WP_TEXT_BUFFER (priv->text_buffer), new_color);
1352 modest_msg_edit_window_insert_image (ModestMsgEditWindow *window)
1355 ModestMsgEditWindowPrivate *priv;
1356 GtkWidget *dialog = NULL;
1358 gchar *filename = NULL;
1360 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1362 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1364 response = gtk_dialog_run (GTK_DIALOG (dialog));
1366 case GTK_RESPONSE_OK:
1367 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1372 gtk_widget_destroy (dialog);
1375 GdkPixbuf *pixbuf = NULL;
1376 GtkTextIter position;
1377 GtkTextMark *insert_mark;
1379 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1382 GdkPixbufFormat *pixbuf_format;
1384 image_file_id = g_open (filename, O_RDONLY, 0);
1385 pixbuf_format = gdk_pixbuf_get_file_info (filename, NULL, NULL);
1386 if ((image_file_id != -1)&&(pixbuf_format != NULL)) {
1387 TnyMimePart *image_part;
1388 TnyStream *image_stream;
1394 mime_types = gdk_pixbuf_format_get_mime_types (pixbuf_format);
1395 if ((mime_types != NULL) && (mime_types[0] != NULL)) {
1396 mime_type = mime_types[0];
1398 mime_type = "image/unknown";
1400 image_part = tny_platform_factory_new_mime_part
1401 (modest_runtime_get_platform_factory ());
1402 image_stream = TNY_STREAM (tny_fs_stream_new (image_file_id));
1404 tny_mime_part_construct_from_stream (image_part, image_stream, mime_type);
1405 g_strfreev (mime_types);
1407 content_id = g_strdup_printf ("%d", priv->last_cid);
1408 tny_mime_part_set_content_id (image_part, content_id);
1409 g_free (content_id);
1412 basename = g_path_get_basename (filename);
1413 tny_mime_part_set_filename (image_part, basename);
1416 insert_mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (priv->text_buffer));
1417 gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (priv->text_buffer), &position, insert_mark);
1418 wp_text_buffer_insert_image (WP_TEXT_BUFFER (priv->text_buffer), &position, g_strdup (tny_mime_part_get_content_id (image_part)), pixbuf);
1419 priv->attachments = g_list_prepend (priv->attachments, image_part);
1420 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1422 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1423 gtk_widget_show_all (priv->attachments_caption);
1424 } else if (image_file_id == -1) {
1425 close (image_file_id);
1434 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1437 ModestMsgEditWindowPrivate *priv;
1438 GtkWidget *dialog = NULL;
1440 gchar *uri = NULL, *filename = NULL;
1442 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1444 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1446 response = gtk_dialog_run (GTK_DIALOG (dialog));
1448 case GTK_RESPONSE_OK:
1449 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
1450 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1455 gtk_widget_destroy (dialog);
1459 GnomeVFSHandle *handle = NULL;
1460 GnomeVFSResult result;
1462 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1463 if (result == GNOME_VFS_OK) {
1464 TnyMimePart *mime_part;
1466 const gchar *mime_type = NULL;
1469 GnomeVFSFileInfo info;
1471 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1472 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1473 mime_part = tny_platform_factory_new_mime_part
1474 (modest_runtime_get_platform_factory ());
1475 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1477 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1479 content_id = g_strdup_printf ("%d", priv->last_cid);
1480 tny_mime_part_set_content_id (mime_part, content_id);
1481 g_free (content_id);
1484 basename = g_path_get_basename (filename);
1485 tny_mime_part_set_filename (mime_part, basename);
1488 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1489 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1491 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1492 gtk_widget_show_all (priv->attachments_caption);
1499 modest_msg_edit_window_attach_file_noninteractive (
1500 ModestMsgEditWindow *window,
1504 ModestMsgEditWindowPrivate *priv;
1506 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1511 file_id = g_open (filename, O_RDONLY, 0);
1512 if (file_id != -1) {
1513 TnyMimePart *mime_part;
1515 const gchar *mime_type;
1519 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1520 mime_part = tny_platform_factory_new_mime_part
1521 (modest_runtime_get_platform_factory ());
1522 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1524 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1526 content_id = g_strdup_printf ("%d", priv->last_cid);
1527 tny_mime_part_set_content_id (mime_part, content_id);
1528 g_free (content_id);
1531 basename = g_path_get_basename (filename);
1532 tny_mime_part_set_filename (mime_part, basename);
1535 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1536 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1538 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1539 gtk_widget_show_all (priv->attachments_caption);
1540 } else if (file_id == -1) {
1547 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1550 ModestMsgEditWindowPrivate *priv;
1551 gboolean clean_list = FALSE;
1553 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1554 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1556 if (att_list == NULL) {
1557 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1561 if (att_list == NULL) {
1562 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1564 GtkWidget *confirmation_dialog = NULL;
1565 gboolean dialog_response;
1567 if (att_list->next == NULL) {
1568 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1569 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1570 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1573 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1575 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1576 gtk_widget_destroy (confirmation_dialog);
1577 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1579 for (node = att_list; node != NULL; node = g_list_next (node)) {
1580 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1581 const gchar *att_id;
1582 priv->attachments = g_list_remove (priv->attachments, mime_part);
1584 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1586 att_id = tny_mime_part_get_content_id (mime_part);
1588 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1590 g_object_unref (mime_part);
1595 g_list_free (att_list);
1599 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1602 ModestMsgEditWindowPrivate *priv;
1603 GdkColor *new_color;
1604 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1606 #ifdef MODEST_HILDON_VERSION_0
1607 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1610 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1612 #endif /*MODEST_HILDON_VERSION_0*/
1614 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1616 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1621 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1624 ModestMsgEditWindowPrivate *priv;
1625 gint new_size_index;
1626 ModestMsgEditWindow *window;
1629 window = MODEST_MSG_EDIT_WINDOW (userdata);
1630 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1631 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1633 if (gtk_check_menu_item_get_active (menu_item)) {
1635 WPTextBufferFormat format;
1637 memset (&format, 0, sizeof (format));
1638 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1640 label = gtk_bin_get_child (GTK_BIN (menu_item));
1642 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1643 format.cs.font_size = TRUE;
1644 format.cs.text_position = TRUE;
1645 format.cs.font = TRUE;
1646 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1647 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1649 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1650 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1651 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1653 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1654 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1655 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1661 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1664 ModestMsgEditWindowPrivate *priv;
1665 gint new_font_index;
1666 ModestMsgEditWindow *window;
1669 window = MODEST_MSG_EDIT_WINDOW (userdata);
1670 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1671 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1673 if (gtk_check_menu_item_get_active (menu_item)) {
1676 label = gtk_bin_get_child (GTK_BIN (menu_item));
1678 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1680 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1681 (gpointer) new_font_index))
1682 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1684 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1685 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1686 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1692 modest_msg_edit_window_set_zoom (ModestWindow *window,
1695 ModestMsgEditWindowPrivate *priv;
1697 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1699 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1700 priv->zoom_level = zoom;
1701 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1705 modest_msg_edit_window_get_zoom (ModestWindow *window)
1707 ModestMsgEditWindowPrivate *priv;
1709 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1711 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1712 return priv->zoom_level;
1716 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1718 ModestWindowPrivate *parent_priv;
1719 GtkRadioAction *zoom_radio_action;
1720 GSList *group, *node;
1722 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1723 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1724 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1726 group = gtk_radio_action_get_group (zoom_radio_action);
1728 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1729 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1733 for (node = group; node != NULL; node = g_slist_next (node)) {
1734 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1735 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1743 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1745 ModestWindowPrivate *parent_priv;
1746 GtkRadioAction *zoom_radio_action;
1747 GSList *group, *node;
1749 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1750 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1751 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1753 group = gtk_radio_action_get_group (zoom_radio_action);
1755 for (node = group; node != NULL; node = g_slist_next (node)) {
1756 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1757 if (node->next != NULL) {
1758 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1761 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1769 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1771 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1772 ModestWindowPrivate *parent_priv;
1773 ModestWindowMgr *mgr;
1774 gboolean is_fullscreen;
1775 GtkAction *fs_toggle_action;
1778 mgr = modest_runtime_get_window_mgr ();
1779 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1781 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1783 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1784 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1785 if (is_fullscreen != active)
1786 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1794 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1796 ModestWindowPrivate *parent_priv;
1797 GtkAction *fs_toggle_action;
1800 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1802 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1803 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1804 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1808 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1811 ModestMsgEditWindowPrivate *priv = NULL;
1812 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1814 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1815 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1817 gtk_widget_show (priv->cc_caption);
1819 gtk_widget_hide (priv->cc_caption);
1820 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1824 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1827 ModestMsgEditWindowPrivate *priv = NULL;
1828 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1830 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1831 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1833 gtk_widget_show (priv->bcc_caption);
1835 gtk_widget_hide (priv->bcc_caption);
1836 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
1840 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1841 ModestRecptEditor *editor)
1843 ModestMsgEditWindowPrivate *priv;
1845 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1846 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1847 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1849 if (editor == NULL) {
1850 GtkWidget *view_focus;
1851 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1853 /* This code should be kept in sync with ModestRecptEditor. The
1854 textview inside the recpt editor is the one that really gets the
1855 focus. As it's inside a scrolled window, and this one inside the
1856 hbox recpt editor inherits from, we'll need to go up in the
1857 hierarchy to know if the text view is part of the recpt editor
1858 or if it's a different text entry */
1860 if (gtk_widget_get_parent (view_focus)) {
1861 GtkWidget *first_parent;
1863 first_parent = gtk_widget_get_parent (view_focus);
1864 if (gtk_widget_get_parent (first_parent) &&
1865 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1866 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1871 editor = MODEST_RECPT_EDITOR (priv->to_field);
1875 modest_address_book_select_addresses (editor);
1880 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1882 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1884 modest_msg_edit_window_open_addressbook (window, NULL);
1888 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1889 gboolean show_toolbar)
1891 ModestWindowPrivate *parent_priv;
1893 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1894 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1896 /* FIXME: we can not just use the code of
1897 modest_msg_edit_window_setup_toolbar because it has a
1898 mixture of both initialization and creation code. */
1901 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1903 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1907 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1908 TnyHeaderFlags priority_flags)
1910 ModestMsgEditWindowPrivate *priv;
1912 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1914 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1915 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1917 if (priv->priority_flags != priority_flags) {
1919 priv->priority_flags = priority_flags;
1921 switch (priority_flags) {
1922 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1923 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1924 gtk_widget_show (priv->priority_icon);
1926 case TNY_HEADER_FLAG_LOW_PRIORITY:
1927 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1928 gtk_widget_show (priv->priority_icon);
1931 gtk_widget_hide (priv->priority_icon);
1938 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1941 ModestMsgEditWindowPrivate *priv;
1942 gint current_format;
1944 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1946 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1948 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1949 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1951 if (current_format != file_format) {
1952 switch (file_format) {
1953 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1954 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1956 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1960 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1961 response = gtk_dialog_run (GTK_DIALOG (dialog));
1962 gtk_widget_destroy (dialog);
1963 if (response == GTK_RESPONSE_OK)
1964 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1968 update_dimmed (window);
1973 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1976 ModestMsgEditWindowPrivate *priv;
1977 WPTextBufferFormat oldfmt, fmt;
1978 gint old_position = 0;
1982 GdkColor *color = NULL;
1983 gboolean bold, bold_set, italic, italic_set;
1984 gboolean underline, underline_set;
1985 gboolean strikethrough, strikethrough_set;
1986 gboolean position_set;
1987 gboolean font_size_set, font_set, color_set;
1990 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1991 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1993 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
1995 /* First we get the currently selected font information */
1996 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
1997 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
1999 switch (oldfmt.text_position) {
2000 case TEXT_POSITION_NORMAL:
2003 case TEXT_POSITION_SUPERSCRIPT:
2011 g_object_set (G_OBJECT (dialog),
2012 "bold", oldfmt.bold != FALSE,
2013 "bold-set", !oldfmt.cs.bold,
2014 "underline", oldfmt.underline != FALSE,
2015 "underline-set", !oldfmt.cs.underline,
2016 "italic", oldfmt.italic != FALSE,
2017 "italic-set", !oldfmt.cs.italic,
2018 "strikethrough", oldfmt.strikethrough != FALSE,
2019 "strikethrough-set", !oldfmt.cs.strikethrough,
2020 "color", &oldfmt.color,
2021 "color-set", !oldfmt.cs.color,
2022 "size", wp_font_size[oldfmt.font_size],
2023 "size-set", !oldfmt.cs.font_size,
2024 "position", old_position,
2025 "position-set", !oldfmt.cs.text_position,
2026 "family", wp_get_font_name (oldfmt.font),
2027 "family-set", !oldfmt.cs.font,
2030 gtk_widget_show_all (dialog);
2031 response = gtk_dialog_run (GTK_DIALOG (dialog));
2032 if (response == GTK_RESPONSE_OK) {
2034 g_object_get( dialog,
2036 "bold-set", &bold_set,
2037 "underline", &underline,
2038 "underline-set", &underline_set,
2040 "italic-set", &italic_set,
2041 "strikethrough", &strikethrough,
2042 "strikethrough-set", &strikethrough_set,
2044 "color-set", &color_set,
2046 "size-set", &font_size_set,
2047 "family", &font_name,
2048 "family-set", &font_set,
2049 "position", &position,
2050 "position-set", &position_set,
2055 if (response == GTK_RESPONSE_OK) {
2056 memset(&fmt, 0, sizeof(fmt));
2062 fmt.italic = italic;
2063 fmt.cs.italic = TRUE;
2065 if (underline_set) {
2066 fmt.underline = underline;
2067 fmt.cs.underline = TRUE;
2069 if (strikethrough_set) {
2070 fmt.strikethrough = strikethrough;
2071 fmt.cs.strikethrough = TRUE;
2076 ? TEXT_POSITION_NORMAL
2077 : ( ( position == 1 )
2078 ? TEXT_POSITION_SUPERSCRIPT
2079 : TEXT_POSITION_SUBSCRIPT );
2080 fmt.cs.text_position = TRUE;
2084 fmt.cs.color = TRUE;
2087 fmt.font = wp_get_font_index(font_name,
2092 if (font_size_set) {
2093 fmt.font_size = wp_get_font_size_index(
2094 font_size, DEFAULT_FONT_SIZE);
2095 fmt.cs.font_size = TRUE;
2097 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2099 gtk_widget_destroy (dialog);
2101 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2105 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2107 ModestMsgEditWindowPrivate *priv;
2109 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2110 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2112 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2114 update_dimmed (window);
2119 update_dimmed (ModestMsgEditWindow *window)
2121 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2122 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2126 gboolean editor_focused;
2128 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2129 editor_focused = gtk_widget_is_focus (priv->msg_body);
2131 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2132 gtk_action_set_sensitive (action, rich_text && editor_focused);
2133 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2134 gtk_action_set_sensitive (action, rich_text && editor_focused);
2135 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2136 gtk_action_set_sensitive (action, rich_text && editor_focused);
2137 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2138 gtk_action_set_sensitive (action, rich_text && editor_focused);
2139 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2140 gtk_action_set_sensitive (action, rich_text && editor_focused);
2141 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2142 gtk_action_set_sensitive (action, rich_text && editor_focused);
2143 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2144 gtk_action_set_sensitive (action, rich_text && editor_focused);
2145 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2146 gtk_action_set_sensitive (action, rich_text && editor_focused);
2147 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2148 gtk_action_set_sensitive (action, rich_text && editor_focused);
2149 widget = priv->font_color_button;
2150 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2151 widget = priv->font_size_toolitem;
2152 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2153 widget = priv->font_face_toolitem;
2154 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2158 setup_insensitive_handlers (ModestMsgEditWindow *window)
2160 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2161 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2164 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2165 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2166 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2167 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2169 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2170 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2171 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2172 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2173 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2174 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2175 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2176 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2177 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2178 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2179 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2180 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2181 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
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, "/ToolBar/ActionsBold");
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, "/ToolBar/ActionsItalics");
2186 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2187 widget = priv->font_color_button;
2188 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2189 widget = priv->font_size_toolitem;
2190 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2191 widget = priv->font_face_toolitem;
2192 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2197 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2199 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2202 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2203 gtk_action_set_sensitive (action, can_undo);
2207 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2210 GtkTextIter match_start, match_end;
2212 if (image_id == NULL)
2215 gtk_text_buffer_get_start_iter (buffer, &iter);
2217 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2218 GSList *tags = gtk_text_iter_get_tags (&match_start);
2220 for (node = tags; node != NULL; node = g_slist_next (node)) {
2221 GtkTextTag *tag = (GtkTextTag *) node->data;
2222 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2223 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2224 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2226 offset = gtk_text_iter_get_offset (&match_start);
2227 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2228 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2232 gtk_text_iter_forward_char (&iter);
2237 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2239 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2240 GtkTextIter real_start, real_end;
2241 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2243 if (gtk_text_iter_compare (start, end) > 0) {
2247 real_start = *start;
2251 GSList *tags = gtk_text_iter_get_tags (&real_start);
2253 for (node = tags; node != NULL; node = g_slist_next (node)) {
2254 GtkTextTag *tag = (GtkTextTag *) node->data;
2255 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2256 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2258 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2260 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2263 } while (gtk_text_iter_forward_char (&real_start)&&
2264 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2268 msg_body_focus (GtkWidget *focus,
2269 GdkEventFocus *event,
2273 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2278 to_field_changed (GtkTextBuffer *buffer,
2279 ModestMsgEditWindow *editor)
2281 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2284 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2285 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2286 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2287 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2291 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2293 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2297 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2299 gboolean rich_text, editor_focused;
2301 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2302 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2303 editor_focused = gtk_widget_is_focus (priv->msg_body);
2306 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2307 else if (!editor_focused)
2308 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2312 reset_modified (ModestMsgEditWindow *editor)
2314 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2315 GtkTextBuffer *buffer;
2317 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2318 gtk_text_buffer_set_modified (buffer, FALSE);
2319 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2320 gtk_text_buffer_set_modified (buffer, FALSE);
2321 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2322 gtk_text_buffer_set_modified (buffer, FALSE);
2323 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2327 is_modified (ModestMsgEditWindow *editor)
2329 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2330 GtkTextBuffer *buffer;
2332 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2333 if (gtk_text_buffer_get_modified (buffer))
2335 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2336 if (gtk_text_buffer_get_modified (buffer))
2338 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2339 if (gtk_text_buffer_get_modified (buffer))
2341 if (gtk_text_buffer_get_modified (priv->text_buffer))
2348 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2350 ModestMsgEditWindowPrivate *priv = NULL;
2352 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2353 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2355 /* check if there's no recipient added */
2356 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2357 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2358 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2359 /* no recipient contents, then select contacts */
2360 modest_msg_edit_window_open_addressbook (window, NULL);
2364 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2366 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2368 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2371 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2378 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2379 ModestMsgEditWindow *window)
2381 modest_msg_edit_window_attach_file (window);
2385 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2387 ModestMsgEditWindow *window)
2389 ModestWindowPrivate *parent_priv;
2394 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2395 selection = gtk_clipboard_wait_for_text (clipboard);
2396 focused = gtk_window_get_focus (GTK_WINDOW (window));
2398 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2399 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2400 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2401 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2405 update_window_title (ModestMsgEditWindow *window)
2407 ModestMsgEditWindowPrivate *priv = NULL;
2408 const gchar *subject;
2410 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2411 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2412 if (subject == NULL || subject[0] == '\0')
2413 subject = _("mail_va_new_email");
2415 gtk_window_set_title (GTK_WINDOW (window), subject);
2420 subject_field_changed (GtkEditable *editable,
2421 ModestMsgEditWindow *window)
2423 update_window_title (window);