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_text_buffer_set_modified (priv->text_buffer, TRUE);
1423 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1424 gtk_widget_show_all (priv->attachments_caption);
1425 } else if (image_file_id == -1) {
1426 close (image_file_id);
1435 modest_msg_edit_window_attach_file (ModestMsgEditWindow *window)
1438 ModestMsgEditWindowPrivate *priv;
1439 GtkWidget *dialog = NULL;
1441 gchar *uri = NULL, *filename = NULL;
1443 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1445 dialog = hildon_file_chooser_dialog_new (GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_OPEN);
1447 response = gtk_dialog_run (GTK_DIALOG (dialog));
1449 case GTK_RESPONSE_OK:
1450 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
1451 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
1456 gtk_widget_destroy (dialog);
1460 GnomeVFSHandle *handle = NULL;
1461 GnomeVFSResult result;
1463 result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
1464 if (result == GNOME_VFS_OK) {
1465 TnyMimePart *mime_part;
1467 const gchar *mime_type = NULL;
1470 GnomeVFSFileInfo info;
1472 if (gnome_vfs_get_file_info_from_handle (handle, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE) == GNOME_VFS_OK)
1473 mime_type = gnome_vfs_file_info_get_mime_type (&info);
1474 mime_part = tny_platform_factory_new_mime_part
1475 (modest_runtime_get_platform_factory ());
1476 stream = TNY_STREAM (tny_vfs_stream_new (handle));
1478 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1480 content_id = g_strdup_printf ("%d", priv->last_cid);
1481 tny_mime_part_set_content_id (mime_part, content_id);
1482 g_free (content_id);
1485 basename = g_path_get_basename (filename);
1486 tny_mime_part_set_filename (mime_part, basename);
1489 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1490 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1492 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1493 gtk_widget_show_all (priv->attachments_caption);
1494 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1501 modest_msg_edit_window_attach_file_noninteractive (
1502 ModestMsgEditWindow *window,
1506 ModestMsgEditWindowPrivate *priv;
1508 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1513 file_id = g_open (filename, O_RDONLY, 0);
1514 if (file_id != -1) {
1515 TnyMimePart *mime_part;
1517 const gchar *mime_type;
1521 mime_type = gnome_vfs_get_file_mime_type_fast (filename, NULL);
1522 mime_part = tny_platform_factory_new_mime_part
1523 (modest_runtime_get_platform_factory ());
1524 stream = TNY_STREAM (tny_fs_stream_new (file_id));
1526 tny_mime_part_construct_from_stream (mime_part, stream, mime_type);
1528 content_id = g_strdup_printf ("%d", priv->last_cid);
1529 tny_mime_part_set_content_id (mime_part, content_id);
1530 g_free (content_id);
1533 basename = g_path_get_basename (filename);
1534 tny_mime_part_set_filename (mime_part, basename);
1537 priv->attachments = g_list_prepend (priv->attachments, mime_part);
1538 modest_attachments_view_add_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1540 gtk_widget_set_no_show_all (priv->attachments_caption, FALSE);
1541 gtk_widget_show_all (priv->attachments_caption);
1542 } else if (file_id == -1) {
1549 modest_msg_edit_window_remove_attachments (ModestMsgEditWindow *window,
1552 ModestMsgEditWindowPrivate *priv;
1553 gboolean clean_list = FALSE;
1555 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1556 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1558 if (att_list == NULL) {
1559 att_list = modest_attachments_view_get_selection (MODEST_ATTACHMENTS_VIEW (priv->attachments_view));
1563 if (att_list == NULL) {
1564 hildon_banner_show_information (NULL, NULL, _("TODO: no attachments selected to remove"));
1566 GtkWidget *confirmation_dialog = NULL;
1567 gboolean dialog_response;
1569 if (att_list->next == NULL) {
1570 gchar *message = g_strdup_printf (_("emev_nc_delete_attachment"),
1571 tny_mime_part_get_filename (TNY_MIME_PART (att_list->data)));
1572 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), message);
1575 confirmation_dialog = hildon_note_new_confirmation (GTK_WINDOW (window), _("emev_nc_delete_attachments"));
1577 dialog_response = (gtk_dialog_run (GTK_DIALOG (confirmation_dialog))==GTK_RESPONSE_OK);
1578 gtk_widget_destroy (confirmation_dialog);
1579 hildon_banner_show_information (NULL, NULL, _("mcen_ib_removing_attachment"));
1581 for (node = att_list; node != NULL; node = g_list_next (node)) {
1582 TnyMimePart *mime_part = (TnyMimePart *) node->data;
1583 const gchar *att_id;
1584 priv->attachments = g_list_remove (priv->attachments, mime_part);
1586 modest_attachments_view_remove_attachment (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
1588 att_id = tny_mime_part_get_content_id (mime_part);
1590 text_buffer_delete_images_by_id (gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->msg_body)),
1592 g_object_unref (mime_part);
1593 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);
1598 g_list_free (att_list);
1602 modest_msg_edit_window_color_button_change (ModestMsgEditWindow *window,
1605 ModestMsgEditWindowPrivate *priv;
1606 GdkColor *new_color;
1607 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1609 #ifdef MODEST_HILDON_VERSION_0
1610 new_color = hildon_color_button_get_color (HILDON_COLOR_BUTTON (priv->font_color_button));
1613 hildon_color_button_get_color (HILDON_COLOR_BUTTON(priv->font_color_button), &col);
1615 #endif /*MODEST_HILDON_VERSION_0*/
1617 wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FORECOLOR, (gpointer) new_color);
1619 gtk_window_set_focus (GTK_WINDOW (window), priv->msg_body);
1624 modest_msg_edit_window_size_change (GtkCheckMenuItem *menu_item,
1627 ModestMsgEditWindowPrivate *priv;
1628 gint new_size_index;
1629 ModestMsgEditWindow *window;
1632 window = MODEST_MSG_EDIT_WINDOW (userdata);
1633 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1634 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1636 if (gtk_check_menu_item_get_active (menu_item)) {
1638 WPTextBufferFormat format;
1640 memset (&format, 0, sizeof (format));
1641 wp_text_buffer_get_current_state (WP_TEXT_BUFFER (priv->text_buffer), &format);
1643 label = gtk_bin_get_child (GTK_BIN (menu_item));
1645 new_size_index = atoi (gtk_label_get_text (GTK_LABEL (label)));
1646 format.cs.font_size = TRUE;
1647 format.cs.text_position = TRUE;
1648 format.cs.font = TRUE;
1649 format.font_size = wp_get_font_size_index (new_size_index, DEFAULT_FONT_SIZE);
1650 wp_text_buffer_set_format (WP_TEXT_BUFFER (priv->text_buffer), &format);
1652 /* if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT_SIZE, */
1653 /* (gpointer) wp_get_font_size_index (new_size_index, 12))) */
1654 /* wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body)); */
1656 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1657 markup = g_strconcat ("<span font_family='Serif'>", gtk_label_get_text (GTK_LABEL (label)), "</span>", NULL);
1658 gtk_label_set_markup (GTK_LABEL (priv->size_tool_button_label), markup);
1664 modest_msg_edit_window_font_change (GtkCheckMenuItem *menu_item,
1667 ModestMsgEditWindowPrivate *priv;
1668 gint new_font_index;
1669 ModestMsgEditWindow *window;
1672 window = MODEST_MSG_EDIT_WINDOW (userdata);
1673 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1674 gtk_widget_grab_focus (GTK_WIDGET (priv->msg_body));
1676 if (gtk_check_menu_item_get_active (menu_item)) {
1679 label = gtk_bin_get_child (GTK_BIN (menu_item));
1681 new_font_index = wp_get_font_index (gtk_label_get_text (GTK_LABEL (label)), DEFAULT_FONT);
1683 if (!wp_text_buffer_set_attribute (WP_TEXT_BUFFER (priv->text_buffer), WPT_FONT,
1684 (gpointer) new_font_index))
1685 wp_text_view_reset_and_show_im (WP_TEXT_VIEW (priv->msg_body));
1687 text_buffer_refresh_attributes (WP_TEXT_BUFFER (priv->text_buffer), MODEST_MSG_EDIT_WINDOW (window));
1688 markup = g_strconcat ("<span font_family='",gtk_label_get_text (GTK_LABEL (label)),"'>Tt</span>", NULL);
1689 gtk_label_set_markup (GTK_LABEL (priv->font_tool_button_label), markup);
1695 modest_msg_edit_window_set_zoom (ModestWindow *window,
1698 ModestMsgEditWindowPrivate *priv;
1700 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1702 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1703 priv->zoom_level = zoom;
1704 wp_text_buffer_set_font_scaling_factor (WP_TEXT_BUFFER (priv->text_buffer), zoom);
1708 modest_msg_edit_window_get_zoom (ModestWindow *window)
1710 ModestMsgEditWindowPrivate *priv;
1712 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), 1.0);
1714 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1715 return priv->zoom_level;
1719 modest_msg_edit_window_zoom_plus (ModestWindow *window)
1721 ModestWindowPrivate *parent_priv;
1722 GtkRadioAction *zoom_radio_action;
1723 GSList *group, *node;
1725 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1726 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1727 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1729 group = gtk_radio_action_get_group (zoom_radio_action);
1731 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (group->data))) {
1732 hildon_banner_show_information (NULL, NULL, _("mcen_ib_max_zoom_level"));
1736 for (node = group; node != NULL; node = g_slist_next (node)) {
1737 if ((node->next != NULL) && gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->next->data))) {
1738 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->data), TRUE);
1746 modest_msg_edit_window_zoom_minus (ModestWindow *window)
1748 ModestWindowPrivate *parent_priv;
1749 GtkRadioAction *zoom_radio_action;
1750 GSList *group, *node;
1752 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1753 zoom_radio_action = GTK_RADIO_ACTION (gtk_ui_manager_get_action (parent_priv->ui_manager,
1754 "/MenuBar/ViewMenu/ZoomMenu/Zoom50Menu"));
1756 group = gtk_radio_action_get_group (zoom_radio_action);
1758 for (node = group; node != NULL; node = g_slist_next (node)) {
1759 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (node->data))) {
1760 if (node->next != NULL) {
1761 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (node->next->data), TRUE);
1764 hildon_banner_show_information (NULL, NULL, _("mcen_ib_min_zoom_level"));
1772 modest_msg_edit_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1774 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1775 ModestWindowPrivate *parent_priv;
1776 ModestWindowMgr *mgr;
1777 gboolean is_fullscreen;
1778 GtkAction *fs_toggle_action;
1781 mgr = modest_runtime_get_window_mgr ();
1782 is_fullscreen = (modest_window_mgr_get_fullscreen_mode (mgr))?1:0;
1784 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1786 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1787 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1788 if (is_fullscreen != active)
1789 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1797 modest_msg_edit_window_toggle_fullscreen (ModestMsgEditWindow *window)
1799 ModestWindowPrivate *parent_priv;
1800 GtkAction *fs_toggle_action;
1803 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
1805 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1806 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action));
1807 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), !active);
1811 modest_msg_edit_window_show_cc (ModestMsgEditWindow *window,
1814 ModestMsgEditWindowPrivate *priv = NULL;
1815 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1817 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1818 gtk_widget_set_no_show_all (priv->cc_caption, TRUE);
1820 gtk_widget_show (priv->cc_caption);
1822 gtk_widget_hide (priv->cc_caption);
1823 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_CC, show, NULL);
1827 modest_msg_edit_window_show_bcc (ModestMsgEditWindow *window,
1830 ModestMsgEditWindowPrivate *priv = NULL;
1831 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1833 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1834 gtk_widget_set_no_show_all (priv->bcc_caption, TRUE);
1836 gtk_widget_show (priv->bcc_caption);
1838 gtk_widget_hide (priv->bcc_caption);
1839 modest_conf_set_bool(modest_runtime_get_conf(), MODEST_CONF_SHOW_BCC, show, NULL);
1843 modest_msg_edit_window_open_addressbook (ModestMsgEditWindow *window,
1844 ModestRecptEditor *editor)
1846 ModestMsgEditWindowPrivate *priv;
1848 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1849 g_return_if_fail ((editor == NULL) || (MODEST_IS_RECPT_EDITOR (editor)));
1850 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1852 if (editor == NULL) {
1853 GtkWidget *view_focus;
1854 view_focus = gtk_window_get_focus (GTK_WINDOW (window));
1856 /* This code should be kept in sync with ModestRecptEditor. The
1857 textview inside the recpt editor is the one that really gets the
1858 focus. As it's inside a scrolled window, and this one inside the
1859 hbox recpt editor inherits from, we'll need to go up in the
1860 hierarchy to know if the text view is part of the recpt editor
1861 or if it's a different text entry */
1863 if (gtk_widget_get_parent (view_focus)) {
1864 GtkWidget *first_parent;
1866 first_parent = gtk_widget_get_parent (view_focus);
1867 if (gtk_widget_get_parent (first_parent) &&
1868 MODEST_IS_RECPT_EDITOR (gtk_widget_get_parent (first_parent))) {
1869 editor = MODEST_RECPT_EDITOR (gtk_widget_get_parent (first_parent));
1874 editor = MODEST_RECPT_EDITOR (priv->to_field);
1878 modest_address_book_select_addresses (editor);
1883 modest_msg_edit_window_select_contacts (ModestMsgEditWindow *window)
1885 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1887 modest_msg_edit_window_open_addressbook (window, NULL);
1891 modest_msg_edit_window_show_toolbar (ModestWindow *self,
1892 gboolean show_toolbar)
1894 ModestWindowPrivate *parent_priv;
1896 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (self));
1897 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1899 /* FIXME: we can not just use the code of
1900 modest_msg_edit_window_setup_toolbar because it has a
1901 mixture of both initialization and creation code. */
1904 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1906 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1910 modest_msg_edit_window_set_priority_flags (ModestMsgEditWindow *window,
1911 TnyHeaderFlags priority_flags)
1913 ModestMsgEditWindowPrivate *priv;
1915 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1917 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1918 priority_flags = priority_flags & (TNY_HEADER_FLAG_HIGH_PRIORITY);
1920 if (priv->priority_flags != priority_flags) {
1922 priv->priority_flags = priority_flags;
1924 switch (priority_flags) {
1925 case TNY_HEADER_FLAG_HIGH_PRIORITY:
1926 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_high", GTK_ICON_SIZE_MENU);
1927 gtk_widget_show (priv->priority_icon);
1929 case TNY_HEADER_FLAG_LOW_PRIORITY:
1930 gtk_image_set_from_icon_name (GTK_IMAGE (priv->priority_icon), "qgn_list_messaging_low", GTK_ICON_SIZE_MENU);
1931 gtk_widget_show (priv->priority_icon);
1934 gtk_widget_hide (priv->priority_icon);
1941 modest_msg_edit_window_set_file_format (ModestMsgEditWindow *window,
1944 ModestMsgEditWindowPrivate *priv;
1945 gint current_format;
1947 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1949 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1951 current_format = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer))
1952 ? MODEST_FILE_FORMAT_FORMATTED_TEXT : MODEST_FILE_FORMAT_PLAIN_TEXT;
1954 if (current_format != file_format) {
1955 switch (file_format) {
1956 case MODEST_FILE_FORMAT_FORMATTED_TEXT:
1957 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), TRUE);
1959 case MODEST_FILE_FORMAT_PLAIN_TEXT:
1963 dialog = hildon_note_new_confirmation (NULL, _("emev_nc_formatting_lost"));
1964 response = gtk_dialog_run (GTK_DIALOG (dialog));
1965 gtk_widget_destroy (dialog);
1966 if (response == GTK_RESPONSE_OK)
1967 wp_text_buffer_enable_rich_text (WP_TEXT_BUFFER (priv->text_buffer), FALSE);
1971 update_dimmed (window);
1976 modest_msg_edit_window_select_font (ModestMsgEditWindow *window)
1979 ModestMsgEditWindowPrivate *priv;
1980 WPTextBufferFormat oldfmt, fmt;
1981 gint old_position = 0;
1985 GdkColor *color = NULL;
1986 gboolean bold, bold_set, italic, italic_set;
1987 gboolean underline, underline_set;
1988 gboolean strikethrough, strikethrough_set;
1989 gboolean position_set;
1990 gboolean font_size_set, font_set, color_set;
1993 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1994 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
1996 dialog = hildon_font_selection_dialog_new (GTK_WINDOW (window), NULL);
1998 /* First we get the currently selected font information */
1999 wp_text_buffer_get_attributes (WP_TEXT_BUFFER (priv->text_buffer), &oldfmt, TRUE);
2000 g_object_set (G_OBJECT (dialog), "font-scaling", priv->zoom_level, NULL);
2002 switch (oldfmt.text_position) {
2003 case TEXT_POSITION_NORMAL:
2006 case TEXT_POSITION_SUPERSCRIPT:
2014 g_object_set (G_OBJECT (dialog),
2015 "bold", oldfmt.bold != FALSE,
2016 "bold-set", !oldfmt.cs.bold,
2017 "underline", oldfmt.underline != FALSE,
2018 "underline-set", !oldfmt.cs.underline,
2019 "italic", oldfmt.italic != FALSE,
2020 "italic-set", !oldfmt.cs.italic,
2021 "strikethrough", oldfmt.strikethrough != FALSE,
2022 "strikethrough-set", !oldfmt.cs.strikethrough,
2023 "color", &oldfmt.color,
2024 "color-set", !oldfmt.cs.color,
2025 "size", wp_font_size[oldfmt.font_size],
2026 "size-set", !oldfmt.cs.font_size,
2027 "position", old_position,
2028 "position-set", !oldfmt.cs.text_position,
2029 "family", wp_get_font_name (oldfmt.font),
2030 "family-set", !oldfmt.cs.font,
2033 gtk_widget_show_all (dialog);
2034 response = gtk_dialog_run (GTK_DIALOG (dialog));
2035 if (response == GTK_RESPONSE_OK) {
2037 g_object_get( dialog,
2039 "bold-set", &bold_set,
2040 "underline", &underline,
2041 "underline-set", &underline_set,
2043 "italic-set", &italic_set,
2044 "strikethrough", &strikethrough,
2045 "strikethrough-set", &strikethrough_set,
2047 "color-set", &color_set,
2049 "size-set", &font_size_set,
2050 "family", &font_name,
2051 "family-set", &font_set,
2052 "position", &position,
2053 "position-set", &position_set,
2058 if (response == GTK_RESPONSE_OK) {
2059 memset(&fmt, 0, sizeof(fmt));
2065 fmt.italic = italic;
2066 fmt.cs.italic = TRUE;
2068 if (underline_set) {
2069 fmt.underline = underline;
2070 fmt.cs.underline = TRUE;
2072 if (strikethrough_set) {
2073 fmt.strikethrough = strikethrough;
2074 fmt.cs.strikethrough = TRUE;
2079 ? TEXT_POSITION_NORMAL
2080 : ( ( position == 1 )
2081 ? TEXT_POSITION_SUPERSCRIPT
2082 : TEXT_POSITION_SUBSCRIPT );
2083 fmt.cs.text_position = TRUE;
2087 fmt.cs.color = TRUE;
2090 fmt.font = wp_get_font_index(font_name,
2095 if (font_size_set) {
2096 fmt.font_size = wp_get_font_size_index(
2097 font_size, DEFAULT_FONT_SIZE);
2098 fmt.cs.font_size = TRUE;
2100 wp_text_buffer_set_format(WP_TEXT_BUFFER(priv->text_buffer), &fmt);
2102 gtk_widget_destroy (dialog);
2104 gtk_widget_grab_focus(GTK_WIDGET(priv->msg_body));
2108 modest_msg_edit_window_undo (ModestMsgEditWindow *window)
2110 ModestMsgEditWindowPrivate *priv;
2112 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2113 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2115 wp_text_buffer_undo (WP_TEXT_BUFFER (priv->text_buffer));
2117 update_dimmed (window);
2122 update_dimmed (ModestMsgEditWindow *window)
2124 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2125 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2129 gboolean editor_focused;
2131 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2132 editor_focused = gtk_widget_is_focus (priv->msg_body);
2134 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2135 gtk_action_set_sensitive (action, rich_text && editor_focused);
2136 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2137 gtk_action_set_sensitive (action, rich_text && editor_focused);
2138 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2139 gtk_action_set_sensitive (action, rich_text && editor_focused);
2140 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2141 gtk_action_set_sensitive (action, rich_text && editor_focused);
2142 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2143 gtk_action_set_sensitive (action, rich_text && editor_focused);
2144 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2145 gtk_action_set_sensitive (action, rich_text && editor_focused);
2146 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2147 gtk_action_set_sensitive (action, rich_text && editor_focused);
2148 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2149 gtk_action_set_sensitive (action, rich_text && editor_focused);
2150 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2151 gtk_action_set_sensitive (action, rich_text && editor_focused);
2152 widget = priv->font_color_button;
2153 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2154 widget = priv->font_size_toolitem;
2155 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2156 widget = priv->font_face_toolitem;
2157 gtk_widget_set_sensitive (widget, rich_text && editor_focused);
2161 setup_insensitive_handlers (ModestMsgEditWindow *window)
2163 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2164 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2167 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2168 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/EmailMenu/SendMenu");
2170 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (send_insensitive_press), window);
2172 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/SelectFontMenu");
2173 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2174 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/BulletedListMenu");
2175 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2176 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu");
2177 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2178 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentLeftMenu");
2179 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2180 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentCenterMenu");
2181 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2182 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/FormatMenu/AlignmentMenu/AlignmentRightMenu");
2183 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2184 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/MenuBar/AttachmentsMenu/InsertImageMenu");
2185 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2186 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsBold");
2187 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2188 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ActionsItalics");
2189 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2190 widget = priv->font_color_button;
2191 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2192 widget = priv->font_size_toolitem;
2193 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2194 widget = priv->font_face_toolitem;
2195 g_signal_connect (G_OBJECT (widget), "insensitive-press", G_CALLBACK (style_insensitive_press), window);
2200 text_buffer_can_undo (GtkTextBuffer *buffer, gboolean can_undo, ModestMsgEditWindow *window)
2202 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2205 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/UndoMenu");
2206 gtk_action_set_sensitive (action, can_undo);
2210 text_buffer_delete_images_by_id (GtkTextBuffer *buffer, const gchar * image_id)
2213 GtkTextIter match_start, match_end;
2215 if (image_id == NULL)
2218 gtk_text_buffer_get_start_iter (buffer, &iter);
2220 while (gtk_text_iter_forward_search (&iter, "\xef\xbf\xbc", 0, &match_start, &match_end, NULL)) {
2221 GSList *tags = gtk_text_iter_get_tags (&match_start);
2223 for (node = tags; node != NULL; node = g_slist_next (node)) {
2224 GtkTextTag *tag = (GtkTextTag *) node->data;
2225 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2226 gchar *cur_image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2227 if ((cur_image_id != NULL) && (strcmp (image_id, cur_image_id)==0)) {
2229 offset = gtk_text_iter_get_offset (&match_start);
2230 gtk_text_buffer_delete (buffer, &match_start, &match_end);
2231 gtk_text_buffer_get_iter_at_offset (buffer, &iter, offset);
2235 gtk_text_iter_forward_char (&iter);
2240 text_buffer_delete_range (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, gpointer userdata)
2242 ModestMsgEditWindow *window = (ModestMsgEditWindow *) userdata;
2243 GtkTextIter real_start, real_end;
2244 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2246 if (gtk_text_iter_compare (start, end) > 0) {
2250 real_start = *start;
2254 GSList *tags = gtk_text_iter_get_tags (&real_start);
2256 for (node = tags; node != NULL; node = g_slist_next (node)) {
2257 GtkTextTag *tag = (GtkTextTag *) node->data;
2258 if (g_object_get_data (G_OBJECT (tag), "image-set") != NULL) {
2259 gchar *image_id = g_object_get_data (G_OBJECT (tag), "image-index");
2261 modest_attachments_view_remove_attachment_by_id (MODEST_ATTACHMENTS_VIEW (priv->attachments_view),
2263 gtk_text_buffer_remove_tag (buffer, tag, start, end);
2266 } while (gtk_text_iter_forward_char (&real_start)&&
2267 (gtk_text_iter_compare (&real_start, &real_end)<=0));
2271 msg_body_focus (GtkWidget *focus,
2272 GdkEventFocus *event,
2276 update_dimmed (MODEST_MSG_EDIT_WINDOW (userdata));
2281 to_field_changed (GtkTextBuffer *buffer,
2282 ModestMsgEditWindow *editor)
2284 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (editor);
2287 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSend");
2288 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2289 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EmailMenu/SendMenu");
2290 gtk_action_set_sensitive (action, gtk_text_buffer_get_char_count (buffer) != 0);
2294 send_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2296 hildon_banner_show_information (NULL, NULL, _("mcen_ib_add_recipients_first"));
2300 style_insensitive_press (GtkWidget *widget, ModestMsgEditWindow *editor)
2302 gboolean rich_text, editor_focused;
2304 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2305 rich_text = wp_text_buffer_is_rich_text (WP_TEXT_BUFFER (priv->text_buffer));
2306 editor_focused = gtk_widget_is_focus (priv->msg_body);
2309 hildon_banner_show_information (NULL, NULL, _("mcen_ib_item_unavailable_plaintext"));
2310 else if (!editor_focused)
2311 hildon_banner_show_information (NULL, NULL, _("mcen_ib_move_cursor_to_message"));
2315 reset_modified (ModestMsgEditWindow *editor)
2317 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2318 GtkTextBuffer *buffer;
2320 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2321 gtk_text_buffer_set_modified (buffer, FALSE);
2322 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2323 gtk_text_buffer_set_modified (buffer, FALSE);
2324 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2325 gtk_text_buffer_set_modified (buffer, FALSE);
2326 gtk_text_buffer_set_modified (priv->text_buffer, FALSE);
2330 is_modified (ModestMsgEditWindow *editor)
2332 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (editor);
2333 GtkTextBuffer *buffer;
2335 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->to_field));
2336 if (gtk_text_buffer_get_modified (buffer))
2338 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->cc_field));
2339 if (gtk_text_buffer_get_modified (buffer))
2341 buffer = modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR(priv->bcc_field));
2342 if (gtk_text_buffer_get_modified (buffer))
2344 if (gtk_text_buffer_get_modified (priv->text_buffer))
2351 modest_msg_edit_window_check_names (ModestMsgEditWindow *window)
2353 ModestMsgEditWindowPrivate *priv = NULL;
2355 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window), FALSE);
2356 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2358 /* check if there's no recipient added */
2359 if ((gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->to_field))) == 0) &&
2360 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->cc_field))) == 0) &&
2361 (gtk_text_buffer_get_char_count (modest_recpt_editor_get_buffer (MODEST_RECPT_EDITOR (priv->bcc_field))) == 0)) {
2362 /* no recipient contents, then select contacts */
2363 modest_msg_edit_window_open_addressbook (window, NULL);
2367 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->to_field)))
2369 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->cc_field)))
2371 if (!modest_address_book_check_names (MODEST_RECPT_EDITOR (priv->bcc_field)))
2374 modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (priv->to_field));
2381 modest_msg_edit_window_add_attachment_clicked (GtkButton *button,
2382 ModestMsgEditWindow *window)
2384 modest_msg_edit_window_attach_file (window);
2388 modest_msg_edit_window_clipboard_owner_change (GtkClipboard *clipboard,
2390 ModestMsgEditWindow *window)
2392 ModestWindowPrivate *parent_priv;
2397 parent_priv = MODEST_WINDOW_GET_PRIVATE (window);
2398 selection = gtk_clipboard_wait_for_text (clipboard);
2399 focused = gtk_window_get_focus (GTK_WINDOW (window));
2401 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CutMenu");
2402 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2403 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/EditMenu/CopyMenu");
2404 gtk_action_set_sensitive (action, (selection != NULL) && (!MODEST_IS_ATTACHMENTS_VIEW (focused)));
2408 update_window_title (ModestMsgEditWindow *window)
2410 ModestMsgEditWindowPrivate *priv = NULL;
2411 const gchar *subject;
2413 priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2414 subject = gtk_entry_get_text (GTK_ENTRY (priv->subject_field));
2415 if (subject == NULL || subject[0] == '\0')
2416 subject = _("mail_va_new_email");
2418 gtk_window_set_title (GTK_WINDOW (window), subject);
2423 subject_field_changed (GtkEditable *editable,
2424 ModestMsgEditWindow *window)
2426 ModestMsgEditWindowPrivate *priv = MODEST_MSG_EDIT_WINDOW_GET_PRIVATE (window);
2427 update_window_title (window);
2428 gtk_text_buffer_set_modified (priv->text_buffer, TRUE);